Pdf.js: Using pdf_viewer with Angular CLI (pseudo-webpack)

Created on 21 Dec 2017  路  9Comments  路  Source: mozilla/pdf.js

Hello,

I am developping an Angular 2+ application with angular-cli (so not a full Webpack) and pdfjs-dist.

I would like to use the pdf_viewer.js component as demonstrated in this example: https://github.com/mozilla/pdf.js/blob/master/examples/components/simpleviewer.js

Successful use of the core

I successfully used pdfjs-dist alone to render pages "manually" (without the PDFViewer component), like this:

import { Component, OnInit } from '@angular/core';

var PDFJS = require('pdfjs-dist');

@Component({/* ... */})
export class PdfViewerComponent implements OnInit{

    ngOnInit() {
        PDFJS.workerSrc = "../node_modules/pdfjs-dist/build/pdf.worker.min.js";
        var pagesWrapper = document.getElementById('ghsPV-pages-wrapper');
    }

    private renderPdf(pdfString: string) {

        PDFJS.getDocument({ data: pdfString }).then(pdf => {

            var pagesWrapper = document.getElementById('ghsPV-pages-wrapper');

            for (let p = 1; p <= pdf.numPages ; p++) {
                pdf.getPage(p).then(page => {

                    var svgHolder = document.createElement('div');
                    svgHolder.classList.add('ghsPV-svgHolder');
                    svgHolder.style.backgroundColor = 'white';
                    svgHolder.style.margin = '1em';

                    var viewport = page.getViewport(1);
                    svgHolder.style.width = viewport.width + 'px';
                    svgHolder.style.height = viewport.height + 'px';

                    page.getOperatorList().then(opList => {
                        var svgGfx = new PDFJS.SVGGraphics(page.commonObjs, page.objs);
                        svgGfx.getSVG(opList, viewport).then(svg => {
                            pagesWrapper.appendChild(svgHolder);
                            svgHolder.appendChild(svg);
                        });
                    });
                });
            }
        });
    }
}

First fail of importing both scripts

However, I didn't manage to use the pdf_viewer correctly, this is my last try:

import { Component, OnInit } from '@angular/core';

require('pdfjs-dist');
var PDFJS = require('pdfjs-dist/web/pdf_viewer.js').PDFJS;

@Component({/* ... */})
export class PdfViewerComponent implements OnInit {

    private pagesWrapper: HTMLElement;
    private pdfViewer: any;
    private pdfLinkService: any;

    ngOnInit() {

        PDFJS.workerSrc = "../node_modules/pdfjs-dist/build/pdf.worker.min.js";

        this.pagesWrapper = document.getElementById('ghsPV-pages-wrapper');

        // Hyperlinks:
        this.pdfLinkService = new PDFJS.PDFLinkService();
        this.pdfViewer = new PDFJS.PDFViewer({
            container: this.pagesWrapper,
            linkService: this.pdfLinkService,
        });
        this.pdfLinkService.setViewer(this.pdfViewer);

        // Scale :
        this.pagesWrapper.addEventListener('pagesinit', function () {
            this.pdfViewer.currentScaleValue = 'page-width';
        });
    }

    private renderPdf(pdfString: string) {
        PDFJS.getDocument({ data: pdfString }).then(pdf => {
            this.pdfViewer.setDocument(pdfString);
            this.pdfLinkService.setDocument(pdfString, null);
        });
    }
}

Here, I have this error message, probably because my PDFJS variable lacks the core features:

ERROR Error: Uncaught (in promise): TypeError: pdfDocument.getPage is not a function
TypeError: pdfDocument.getPage is not a function
    at PDFViewer.setDocument (pdf_viewer.js:2470)
    at eval (ghs-pdf-viewer.component.ts:123)
    at ZoneDelegate.invoke (zone.js:392)
    at Object.onInvoke (core.js:4629)
    at ZoneDelegate.invoke (zone.js:391)
    at Zone.run (zone.js:142)
    at eval (zone.js:873)
    at ZoneDelegate.invokeTask (zone.js:425)
    at Object.onInvokeTask (core.js:4620)
    at ZoneDelegate.invokeTask (zone.js:424)
    at PDFViewer.setDocument (pdf_viewer.js:2470)
    at eval (ghs-pdf-viewer.component.ts:123)
    at ZoneDelegate.invoke (zone.js:392)
    at Object.onInvoke (core.js:4629)
    at ZoneDelegate.invoke (zone.js:391)
    at Zone.run (zone.js:142)
    at eval (zone.js:873)
    at ZoneDelegate.invokeTask (zone.js:425)
    at Object.onInvokeTask (core.js:4620)
    at ZoneDelegate.invokeTask (zone.js:424)
    at resolvePromise (zone.js:824)
    at eval (zone.js:876)
    at ZoneDelegate.invokeTask (zone.js:425)
    at Object.onInvokeTask (core.js:4620)
    at ZoneDelegate.invokeTask (zone.js:424)
    at Zone.runTask (zone.js:192)
    at drainMicroTaskQueue (zone.js:602)
    at <anonymous>

Second fail with .angular-cli.json

I also tried to include both JavaScript files via .angular-cli.json:

{
    "apps": [
        {
            "assets": [
                "assets",
                "manifest.json"
            ],
            "styles": [
                "styles.scss",
                "../node_modules/pdfjs-dist/web/pdf_viewer.css"
            ],
            "scripts": [
                "../node_modules/pdfjs-dist/build/pdf.js",
                "../node_modules/pdfjs-dist/web/pdf_viewer.js"
            ]
        }
    ]
}

And just declare PDFJS in my component:

declare var PDFJS: any;

In this case, I have no error message, but the PDFJS.getDocument() promise is never executed, so nothing happens.

[TL;DR] Question

So my question is: what is the correct method of importing both pdf.js and pdf_viewer.js scripts in Angular?
I did check the webpack example but this example only uses the core pdf.js, not pdf_viewer.js.

As a side note, and I think it's related to how I should use PDFJS with Angular: my PDFJS.workerSrc does not work either (404 Not Found), so if anyone has an idea...

All 9 comments

@LeoDupont If interested, I've built a wrapper for angular 2+ apps https://github.com/VadimDez/ng2-pdf-viewer

Even though the situation described here isn't identical to the one in issue #9239, that one might still be relevant/helpful here.

However, as explained in CONTRIBUTING.md, this issue isn't currently valid without a complete (and runnable) example; please refer to the quote below (emphasis mine).

If you are developing a custom solution, first check the examples at https://github.com/mozilla/pdf.js#learning and search existing issues. If this does not help, please prepare a short well-documented example that demonstrates the problem and make it accessible online on your website, JS Bin, GitHub, etc. before opening a new issue or contacting us on the IRC channel -- keep in mind that just code snippets won't help us troubleshoot the problem.

Closing since the issue is not really actionable. Consider using the wrapper provided above or provide a full example.

@LeoDupont Could you achieve to implement pdfjs viewer in your angular 2.x app?

@MstfTkrsln I decided to use @VadimDez 's wrapper : https://github.com/VadimDez/ng2-pdf-viewer.
It's not as complete or flexible as using pure pdfjs, but it works at least.

@LeoDupont but it does not use web/viewer.html template according to demo.
I would like to use this template but i couldn't find a way how can i import this prepared template in my angular component.

@MstfTkrsln did you found any solution on howw to integrate pdf.js in angular 2+ ??

@lahcen-hazam I copied prebuilt version in my assets folder. Then i navigate ..\assets\viewer.html?file=mypdf.pdf with file parameter then it's working. I couldn't find another way to accomplish this. the documentation for angular 2.x was not enoughf.
check also here

@MstfTkrsln Thanks sir, i will try this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

timvandermeij picture timvandermeij  路  4Comments

liuzhen2008 picture liuzhen2008  路  4Comments

kleins05 picture kleins05  路  3Comments

hp011235 picture hp011235  路  4Comments

azetutu picture azetutu  路  4Comments