4

I have the export button which hit API and send response in .csv type. When i hit the API, the response said status: 200 but i getting HttpErrorResponse in the console, and got this error

SyntaxError: Unexpected token T in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttpRequest.onLoad

I have tried to ask my friend that I have to change my Header, but i don't understand how to do it properly. Should i set the header within Token Interceptor as same as when i set the token of the headers (if ya, how can I do that?)? Or how can i solve my problem?

This is the function that the button triggered:

onExport = () => {
    this._service.getDataExport(1, 1, this.filter).subscribe(
      res => {
        console.log(res);
        // const filename = `MediaPreparation.csv`;
        // const blob = new Blob([res.data], { type: 'text/csv' });
        // saveAs(blob, filename);
      },
      err => console.log(err)
    );
  }

This this is the service that I hit:

getDataExport = (page = 1, perPage = 1, filter = null): Observable<any> => {
   const _url = `${this.base_url}/api/v1/media-preparation/export`;

   return this.http.post(_url, {
     page : page.toString(),
     perPage: perPage.toString(),
     filter : filter
   });
}

and this is the Token Inteceptor:

import { AuthService } from './auth.service';
import { Injectable, Injector } from '@angular/core';
import { HttpInterceptor } from '@angular/common/http';

@Injectable()
export class TokenInterceptorService implements HttpInterceptor {

  constructor(private injector: Injector) { }

  intercept(req, next) {
    const authService = this.injector.get(AuthService);
    const tokenizedReq = req.clone({
      setHeaders: {
        Authorization: `Bearer ${authService.getToken()}`
      }
    });

    return next.handle(tokenizedReq);
  }
}

Thanks for helping, and I am sorry for the bad explanation, I stil beginner in Angular.

2
  • What do you want to do with the CSV file on the frontend? Is it to be downloadable for the client? - Most of the time the BE will handle files as CSV, and provide an endpoint which return json data. I am not sure why exactly you want the file on the FE. That might help answer your question. Cheers Commented Jan 18, 2019 at 8:20
  • @JonasPraem ya, i want to download the data as soon as the response is completed. Ah i have tried to change the content-type but i still got the same error Commented Jan 18, 2019 at 8:25

1 Answer 1

9

The reason is easy, HttpClient is trying to parse your response as JSON, since it's the most common scenario and the default action.

To prevent HttpClient to parse your response, you have to put responseType: 'text' in your httpOptions:

private httpOptions = {
  headers: new HttpHeaders({}),
  responseType: 'text'
};

Then use this object as last parameter of your http method (I suppose get):

this.http.get(url, httpOptions)
  .subscribe(res => {
    // res is just a string, you have to split it on new lines and commas
    // or you can use a third part library
  });

Note:

Some servers may need to add some not-standard Accept header, for example:

headers: new HttpHeader({
  Accept: 'text/csv'
});

Or

headers: new HttpHeader({
  Accept: 'application/csv'
});

Or (standard but not semantic):

headers: new HttpHeader({
  Accept: 'plain/text'
});
Sign up to request clarification or add additional context in comments.

3 Comments

It works mate, but i got new error in command prompt that said "Types of property 'responseType' are incompatible. Type 'string' is not assignable to type '"json"'. How can i fix that?
Just avoid any generic (no types between < and >)
Also possible responseType: 'text' as' text'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.