user3097695
user3097695

Reputation: 1274

html2canvas: Error Uncaught (in promise): [object undefined] angular 6

I am using html2canvas to convert html to image, then export as pdf file. Here is my steps using this package:

  1. yarn add html2canvas

  2. add code to convert html to image.

    async export(comp, doc, save) {
      // create pdf file
      let height = REPORT_PAGE.top;
      const header = comp.reportHeader.nativeElement;
      const headerCanvas = await html2canvas(header, {svgRendering: true});
      height = REPORT_PAGE.top;
      let imgHeightHtml = REPORT_PAGE.header * REPORT_PAGE.width / headerCanvas.width;
      let contentDataURL = headerCanvas.toDataURL('image/png');
      doc.addImage(contentDataURL, 'PNG', REPORT_PAGE.left, height, REPORT_PAGE.width, imgHeightHtml);
      if (save) {
        doc.save('myreport.pdf');
      } else {
        doc.addPage();
      }
    }
    

where comp is the angular component, doc is jsPDF, save is boolean. The following error will throw when the html2canvas is called.

Uncaught (in promise): [object Undefined]
at resolvePromise (zone.js:814)
at resolvePromise (zone.js:771)
at zone.js:873
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
at Object.onInvokeTask (core.js:4053)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
at drainMicroTaskQueue (zone.js:595)
at push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask (zone.js:500)
at ZoneTask.invoke (zone.js:485)

html2canvas is a very useful package, but this error is really bad. Please help.

Upvotes: 4

Views: 8247

Answers (2)

john
john

Reputation: 41

I had the same issue and this fixed it:

html2canvas(element, {
    ignoreElements: (node) => {
        return node.nodeName === 'IFRAME';
    }
}).then((canvas) => {
    ...
});

source: https://github.com/niklasvh/html2canvas/issues/1593#issuecomment-489059452

Upvotes: 4

Omer Gurarslan
Omer Gurarslan

Reputation: 1027

I have also run into the same issue and concluded that it is a bug. After a quick search, I came across this thread:

https://github.com/niklasvh/html2canvas/issues/1593

...where a user (adamszeibert) pointed out the responsible piece of code:

I've found that in my case the error was coming from iframeLoader defined in https://github.com/niklasvh/html2canvas/blob/master/src/Clone.js at around line 572.

I could solve the issue by changing the code to return Promise.resolve(cloneIframeContainer); I'm pretty sure this fix breaks a lots of other uses cases, but for what I needed it solved the issue.

Solution 1:

As of today, there is an open pull request for the solution:

https://github.com/niklasvh/html2canvas/pull/1681

Solution 2:

Use runOutsideAngular method of NgZone.

Step 1: Import NgZone from Angular Core:

import {NgZone} from '@angular/core';

Step 2: Add ngZone to component constructor:

  constructor(
              ...
              ...
              private _ngZone: NgZone) {
                  ...
              }

Step 3: Encapsulate your html2canvas code as follows:

  public saveAsImage = () => {

    this._ngZone.runOutsideAngular(() => {

        html2canvas(document.getElementsByTagName('canvas')[0]).then(canvas => {
            let a = document.createElement('a');
            a.href = canvas.toDataURL("image/jpeg").replace("image/jpeg", "image/octet-stream");
            a.download = 'Some Filename.jpg';
            a.click();
          });
    });
  };

Upvotes: 2

Related Questions