Home > database >  Displaying a pdf using ng2-pdf-viewer in Angular
Displaying a pdf using ng2-pdf-viewer in Angular

Time:01-22

I am trying to use ng2-pdf-viewer to display a pdf. I am obtaining the pdf as a response from a post request. The functionality is that when I click on Dispute for Dognosis the pdf should be displayed.UI

I get the following error in my console logs console logs. I am getting a valid response in my api call valid response in browser valid response in postman

here is the html code for the link

<a (click)="displayFile()" target="_blank" >{{
 element.dDocTitle
  }}</a>

here are some other functions used

displayFile() {
    this.tempBlob = null;
    this.backendService.downloadFileMock().subscribe((retFileData: any) => {
    this.tempRetFileData = retFileData;
    this.tempBlob = new Blob([retFileData], { type: 'application/pdf' });
    const fileReader = new FileReader();
    fileReader.onload = () => {
        this.pdfSrc = new Uint8Array(fileReader.result as ArrayBuffer);
        this.displayOverlay(this.pdfEle);
    };
    fileReader.readAsArrayBuffer(this.tempBlob);
    });
  }

  displayOverlay(ele: ElementRef) {
    let displayElement = ele.nativeElement;
    this.renderer.setStyle(displayElement, 'display', 'block');
   }

here is the html code for pdf-viewer

<div #pdf id="overlay" (click)="closeOverlay(pdfEle)">
  <div
    id="overlay-content"
    style="overflow: auto"
    (click)="$event.stopPropagation()"
  >
    <div >
      <div id="popup-header">
        File Preview
        <button id="close-button" (click)="closeOverlay(pdfEle)">X</button>
      </div>
   </div>
    <div id="scroll">
      <div>
        <div>
      <pdf-viewer
        [src]="pdfSrc"
        [rotation]="0"
        [original-size]="true"
        [show-all]="true"
        [fit-to-page]="false"
        [zoom]="1"
        [zoom-scale]="'page-width'"
        [stick-to-page]="false"
        [render-text]="true"
        [external-link-target]="'blank'"
        [autoresize]="true"
        [show-borders]="false"
        style="height: 2500px; width: 900px"
      ></pdf-viewer>
             </div>
       </div>
     </div>
  </div>
</div>

here is the api call I made

 downloadFileMock() {
   let formData = new FormData();
   formData.append('fileName', "artghh.pdf")
   const headers = new HttpHeaders().set('Access-Control-Allow-Origin', '*');

    return this.http
    .post(this.baseURL   '/downloadMock' ,formData);
  }

Please feel free to reach out for any further clarifications.

CodePudding user response:

This is an educated guess, based on the fact that you apparently get a good response when using postman, but not when your Angular code posts to the same location. Also the fact that you are setting the Access-Control-Allow-Origin header in your client request.

You probably are having a problem with CORS.

Postman will always work, because it doesn't require CORS...but the browser does.

And clearly, you have a misunderstanding about how CORS works, because that Access-Control-Allow-Origin header is something that the server should be setting in the response to your post, not something that you should be sending from the client.

So, it's probably a back-end configuration issue.

You haven't specified what your back-end is, so I can't offer any further advice except that you read up on the documentation for whatever server / framework you are using on the back-end, and figure out how to set up CORS properly there.

CodePudding user response:

The displayFile() needs some changes :

displayFile() {
  this.tempBlob = null;
  this.backendService.downloadFileMock().subscribe((retFileData: any) => {
    this.tempRetFileData = retFileData;

    // Check the response type
    if (retFileData.type === 'application/pdf') {
      this.tempBlob = new Blob([retFileData], { type: 'application/pdf' });
      const fileReader = new FileReader();
      fileReader.onload = () => {
        // Convert ArrayBuffer to Uint8Array
        this.pdfSrc = new Uint8Array(fileReader.result as ArrayBuffer);
        this.displayOverlay(this.pdfEle);
      };
      fileReader.readAsArrayBuffer(this.tempBlob);
    } else {
      console.error('Invalid response type. Expected "application/pdf", got', retFileData.type);
    }
  });
}

This code snippet will check the response type before processing the data, and if it's not 'application/pdf' then it will show an error message.

It also converts the ArrayBuffer to Uint8Array before passing it to pdf-viewer component.

And make sure to import the required modules at the top of the file like Blob, FileReader, Uint8Array.


Here's an example of what the downloadFileMock() function might look like:

downloadFileMock() {
    let formData = new FormData();
    formData.append('fileName', "artghh.pdf")
    const headers = new HttpHeaders().set('Access-Control-Allow-Origin', '*');
    return this.http.post(this.baseURL   '/downloadMock' ,formData,{headers});
}

This function creates a new FormData object, appends the file name to it, and sends it as the body of the request. The headers are set to allow CORS. The function returns an observable of the response so that it can be subscribed to in the displayFile() function.

Make sure that the baseURL is correct and the endpoint '/downloadMock' is available on your server and also the server should return the pdf as response.

Hope this Helps!!

  • Related