Invalid PDF Structure with ng2-pdfjs-viewer

2.5k views Asked by At

I am trying to the load the PDF in ng2-pdfjs-viewer but I get "Invalid PDF Structure, undefined error". The backend is returning the data to me in a Blob format but when I feed to the UI it gives the above error:

HTML Code:

  <div class="mlp-flex-container mlp-flex-container--relative mlp-flex-item">
    <div *ngIf="!showReport" class="informationMessage">Please Select a Trader</div>
    <ng2-pdfjs-viewer *ngIf="showReport" #pdfViewer class="pdfViewer"></ng2-pdfjs-viewer>
  </div>

JS Code:

  private async getDataAsync(message: ReportGroupMessage) {
    const rawData = await this.croDashboardPerformanceReportsDataService.getPerformanceReportsLocationDataAsync(message);
    this.pdfViewer.pdfSrc = rawData;
    this.pdfViewer.refresh();
  }

  public getPerformanceReportsLocationDataAsync(reportGroupMessage: ReportGroupMessage | any): Promise<any> {
    debugger
    const url = `Confidential URL`;
    return this.http.get(url, { responseType: 'blob' })
      .pipe(
        map((result: any) => {
          return result;
        })
      ).toPromise();
  }

Can someone please help?

1

There are 1 answers

0
Xleg On

I had the same problem when sending my pdf file from my node.js api as buffer to my angular frontend. I ended up by sending the file as base64 to the frontend. There I converted the base64 string to an ArrayBuffer.

For example my api route:

const fs = require('fs');
const fsPromises = fs.promises;

router.get("/", async (req, res) => {
  try {
    // Set absolute path
    const fileAbsolutePath = req.query.fileAbsolutePath;
    // Read file as base64 string
    const base64Source = await fsPromises.readFile(fileAbsolutePath, { encoding: 'base64'});
    return res.status(200).send({ pdf: base64Source.toString('utf-8') });
  } catch (e) {
    logger.error("Error while sending the PDF File: ", e);
    return res.status(500).send(e.message);
  }
});

My component.ts file:

@ViewChild('pdfViewer') public pdfViewer;

getPDFSource(fileAbsolutePath: string): void {
    this.viewerService.getPDF(fileAbsolutePath).pipe(take(1)).subscribe(source => {
      // Convert base64 to ArrayBuffer
      const myBuffer = Uint8Array.from(atob(source.pdf), c => c.charCodeAt(0));
      // Set the source of the pdf viewer
      this.pdfViewer.pdfSrc = myBuffer;
      // Refresh the pdf viewer
      this.pdfViewer.refresh();
    });
  }

As described here you can convert the the base64 string to an ArrayBuffer.
In your .html file define the ng2-pdfjs-viewer as template variable to access the viewer trough a viewchild in your .ts file.

My viewer.service.ts file:

getPDF(fileAbsolutePath: string): Observable<any> {
    return this.http.get<any>(`${apiUrl}`?fileAbsolutePath=${fileAbsolutePath});
  }