1

I have the below code to download the JSON object from url. But the download is not happening.

     openDownloadWindow() {
    this.downloadPdf().subscribe(pdfBlob => {
        const url = window.URL.createObjectURL(pdfBlob);
        window.open(url);
    });
}
public downloadPdf() {
  const url =  'http://161.202.31.51:8185/sgdocsrv/ar/getARList';
  const headers = new Headers();
  headers.append('Authorization', 'JWT ' + localStorage.getItem('id_token'));
  return this.http.get(url, {  headers: headers, responseType: ResponseContentType.Blob }).map(
      (res) => {
          return new Blob([res.blob()], { type: 'application/pdf' });
      });
}
Nancy
  • 911
  • 7
  • 26
  • 54
  • Please provide us your backend code. Have you try to do someting like this ? `this.downloadPdf().subscribe(res => console.log(res));` – Yanis-git Apr 24 '18 at 10:24
  • I have an array of json object which is displayed in my front end . I now want to download all these contents to PDF – Nancy Apr 24 '18 at 10:37

2 Answers2

1

there's a bunch of things to change so here's what I had working :

public getMeMyPDF(): any {
    const url =  'http://161.202.31.51:8185/sgdocsrv/ar/getARList';
    this.PDF = this.http.get(url, {
      observe: 'response',
      headers: new HttpHeaders({'Content-Type', 'application/pdf', 'Authorization',
      'JWT ' + localStorage.getItem('id_token')}),
      responseType: 'text' as 'text' // <-- this part is rediculous but necessary
    }).catch(this.handleError);
    return this.PDF;
}

I personally had it in a post request but get is obviously the more common and obvious scenario.

I finally stumbled upon this in a long github issue on angular.

the double trick was to have a cast from text to text and to have your whole options inside the http call as dirty as that may look.

I also threw in my syntax where I first declared a var and returned that (not necessarily a waste of a line if suddenly you need to console log it again), and also added a catch which you can handle in a global catch function for all your APIs.

Don't forget to like, favorite and subscribe to your api, wherever you call it. (even if you don't do anything inside the subscribe (in your case you will))

here's what I did back in my component that calls my apiservice.getMeMyPDF :

getMeAPDF(){
    this.apiService.getMeMyPDF().subscribe(res => {
      if(res !== null && res !== undefined){
        this.saveToFileSystem(res.body);
      }
    }, (error) => console.log(error), () => {});
  }

  private saveToFileSystem(response) {
    const blob = new Blob([response], { type: 'text/pdf' });
    const d = new Date();
    saveAs(blob, 'WOWPDF_' + this._datepipe.transform(d, 'yyyyMMdd_HHmmss') + '.pdf');
  }
tatsu
  • 2,316
  • 7
  • 43
  • 87
  • I am facing the below issue : Failed to compile. Module parse failed: Unexpected token You may need an appropriate loader to handle this file type. | this.PDF = this.http.get(url, { | observe: 'response', | headers: new http_2.HttpHeaders({ 'Content-Type': , 'application/pdf': , 'Authorization': , | 'JWT ': +localStorage.getItem('id_token') }), | responseType: 'text' // <-- this part is rediculous but necessary – Nancy Apr 24 '18 at 13:32
  • well you use `Headers` not `HttpHeaders` did you `import { HttpHeaders } from '@angular/common/http';` ? also try with your own method `Headers` instead. Just keep hitting the code with a hammer until it works :D – tatsu Apr 24 '18 at 13:37
  • also I'm not entirely sure your `localStorage.getItem('id_token')` can necessarily be called within that specific context you might have to initialize it as a var outside the http call? I personally didn't have Auth. I updated my answer a bit. – tatsu Apr 24 '18 at 13:43
  • @Nancy so? is it working? mark me as answer if yes :) – tatsu Apr 25 '18 at 15:57
  • Yes !! I have posted another question. Could you please post any replies? https://stackoverflow.com/questions/50018124/download-pdf-is-not-rendering-the-complete-list-of-data-from-ngfor-using-html2ca – Nancy Apr 25 '18 at 16:46
0

You need to create a new function that subscribes to your downloadPdf function and opens a link to the blob:

openDownloadWindow() {
    this.downloadPdf().subscribe(pdfBlob => {
        const url = window.URL.createObjectURL(pdfBlob);
        window.open(url);
    });
}
Kelvin Lai
  • 2,209
  • 7
  • 24
  • 26
  • Do i need to call openDownloadWindow function from html ? And where should i mention the url from where i get the JSON object.? – Nancy Apr 24 '18 at 10:34
  • @Nancy Just replace the call to `downloadPdf` to `openDownloadWindow`. If you want to specify a URL you can change the function signature of both `downloadPdf` and `openDownloadWindow` to accept a `string` as a parameter. – Kelvin Lai Apr 24 '18 at 10:37
  • I am getting error property downloadPdf doesnt exist – Nancy Apr 24 '18 at 10:42
  • @Nancy you need to put the `openDownloadWindow` function in the same class as `downloadPdf`. – Kelvin Lai Apr 24 '18 at 10:46
  • Okay I have modified my code I have posted to what you have mentioned. I am getting error in headers and responsecontentType – Nancy Apr 24 '18 at 10:51
  • This code actually opens a new window, but I get error Failed to download PDF – Nancy Apr 24 '18 at 13:48