I have an angular app and with 'npm run build-desktop-win' an electron client is being created. After launching the exe, everything works fine except the pdf-viewer. In web browser the pdf are being displayed normally and also printed with print(), but neither ng2-pdf-viewer nor jsPDF seem to work. I am stuck here since days. I tried a lot of of workaround found here as well but nothing. Any help please.
My code:
component.html
<pdf-viewer id="documento" [src]="pdfSrc"
[render-text]="true"
[original-size]="false"
[autoresize]="true"
style="display: block;"
[zoom]="activeZoom"
`></pdf-viewer>`
pdfGenerationService.ts
import {Injectable, Inject} from '@angular/core';
import * as jsPDF from 'jspdf';
import {DOCUMENT} from '@angular/common';
@Injectable()
export class PDFGenerationService {
constructor(@Inject(DOCUMENT) private _document: any) {}
public generatePDF(data: any, save: boolean): string {
let arr = [];
if (!Array.isArray(data)) {
arr.push(data);
} else {
arr = data;
}
const doc = new jsPDF();
for (let i = 0; i < arr.length; i++) {
doc.text(20, 10, arr[i].name);
doc.text(10, 80, arr[i].description);
if (i < arr.length - 1) {
doc.addPage();
}
}
const string = doc.output('datauristring');
if (save) {
doc.save('selectedReports.pdf');
}
return string;
}
public b64toBlob(b64Data: any, contentType: any, sliceSize?: any): any {
const str = b64Data.split(',')[1];
contentType = contentType || '';
sliceSize = sliceSize || 512;
const byteCharacters = atob(str);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {type: contentType});
return blob;
}
public printPreviewPDF(pdfSrc: string, content: string) {
const blob = this.b64toBlob(pdfSrc, content);
const blobUrl = URL.createObjectURL(blob);
const doc = this._document.createElement('iframe');
doc.src = blobUrl;
this._document.body.appendChild(doc);
doc.style.position = 'absolute';
doc.style.left = '10000px';
doc.style.right = '10000px';
doc.style.width = '0px';
doc.style.height = '0px';
this._document.body.appendChild(doc);
doc.contentWindow.print();
}
}
component.ts
this.pdfSrc = this._pdfGenerationService.generatePDF(report, false);
The error I am getting is:
Uncaught in promise: DataCloneError: Failed to execute posMessage on Worker: TypeError: d.request is not a function could not be cloned.
Error: Failed to execute 'postMessage' on 'Worker': d.request is not a function could not be cloned..
Look forward to hear from you guys. This is my first issue, so sorry if something can go wrong posting the issue.
Hi etor,
How did you fix that?
@kurthybela Actually I could not fix it, I am still waiting for a solution.
I have the same issue. I know for a fact that ng2-pdf-viewer worked fine with a previous combination of Electron, Angular, and ng2-pdf-viewer.
@kurthybela @etor I found a way to solve this issue. It is related to the way pdf.js detects features.
It tries to determine if the environment is node.js (https://github.com/mozilla/pdf.js/blob/master/src/shared/is_node.js). If pdf.js detects we are on Node, they will load the PDF with Node's http package. Sadly, Angular's CLI will break the import, because it doesn't assume node.js as a context and will import the http package as an empty object.
My quick fix to this is to do the following somewhere in your Angular app root (I have it in app.module.ts):
if (typeof window !== "undefined" && typeof window["process"] !== "undefined") {
delete window["process"];
}
If you need process I'm afraid you will need to find another fix (I'd probably just move it to another variable).
Thank you @wartab for your solution.
Unfortunately I can't get it to work.
I think my problem is that I didn't understand what you've meant by saying:
...somewhere in your Angular app root (I have it in app.module.ts):
I've tryied lots of combination with your suggestted code, but can't make it to work.
Please, can you upload your app.module.ts code, so we can see the correct way for fixing this error.
Thanks
We ended up having trouble making it work this way in app.module.ts.
The way to make it work is adding in the polyfills.ts file:
// Necessary to get PDF.JS to work in Electron.
// https://github.com/mozilla/pdf.js/issues/10093
// https://github.com/VadimDez/ng2-pdf-viewer/issues/358
if (typeof window !== "undefined" && typeof window["process"] !== "undefined") {
delete window["process"];
}
Also note that in the upcoming release of pdfjs-dist, this will no longer be an issue as they have fixed it a couple of days ago:
https://github.com/mozilla/pdf.js/issues/10093
@wartab you made my day! Thanks a lot!
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Most helpful comment
We ended up having trouble making it work this way in app.module.ts.
The way to make it work is adding in the polyfills.ts file:
Also note that in the upcoming release of pdfjs-dist, this will no longer be an issue as they have fixed it a couple of days ago:
https://github.com/mozilla/pdf.js/issues/10093