Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to receive file with type csv from API response

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.

like image 431
Raka Pratama Avatar asked Jan 26 '23 21:01

Raka Pratama


1 Answers

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'
});
like image 100
Cristian Traìna Avatar answered Jan 31 '23 22:01

Cristian Traìna