0

I work on create PDF with pdfmake and i get images of many charts with html2canvas.
How i can get the value of the Promise of html2canvas return?

CODE

    var img = { token: html2canvas(document.getElementById("chartContainer")).then(canvas => {
    return canvas.toDataURL("image/jpeg,1.0")
    }).then(canvas =>{return canvas})}

    console.log (img.token); // Promise { <state>: "pending" }
    alert(img.token); // Object Promise

I want to use images outside the function. Thanks for your help!

stefo91
  • 618
  • 6
  • 16
  • You have two choices: 1. Use a callback in your `then` rather than returning a value 2. Use Async/Await. it appears you want to think of this async operation in a very synchronous way, so I recommend investigating [Async/Await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await). – Randy Casburn May 12 '18 at 17:15
  • The whole point is that you can't get the value while the promise is still pending. Just put the `alert`/`console.log` inside the `then` callback. – Bergi May 12 '18 at 18:03

2 Answers2

1

If promises and .then are confusing, and you are somehow trying to get values out of the future to use in the here and now, consider async/await, which allows you to write asynchronous code in a way which sorta kinda looks synchronous:

const canvas = await html2canvas(document.getElementById("chartContainer"));
const token = canvas.toDataURL("image/jpeg,1.0");
const img = { token };

console.log (img.token);
alert(img.token);

Internally, the above code is transpiled or interpreted in such as way as to wait for the html2canvas promise to fulfill, using the equivalent of .then. In other words, it ends up looking like this:

html2canvas(document.getElementById("chartContainer"))
  .then(canvas => {
    const token = canvas.toDataURL("image/jpeg,1.0");
    const img = { token };

    console.log (img.token);
    alert(img.token);
  });

Or, if you don't want to use async/await for some reason, you could just write it like this to start with.

PS. Assuming the code above is inside a function, it would need to be an async function.

0

You have to wait for the promise to complete. When the promise completes, the function you passed into .then(/*...*/) is called.

You also don't need to use an additional .then after toDataURL, because toDataURL runs synchronously (it doesn't return a promise). You only need to use .then for functions that return a promise.

So you can rewrite it like this instead:

html2canvas(document.getElementById("chartContainer"))
    .then(canvas => {
        // This code will run once the promise has completed
        var img = { token: canvas.toDataURL("image/jpeg,1.0") };
        console.log(img.token);
        alert(img.token);
    });
grovesNL
  • 6,016
  • 2
  • 20
  • 32
  • OK, thanks you but i want to use img outside to create my Docdefinition for pdfmake: var img = null; html2canvas(document.getElementById("chartContainer")) .then(canvas => { // This code will execute once the promise has completed img = { token: canvas.toDataURL("image/jpeg,1.0") }; }); console.log();//null alert(); //null – stefo91 May 12 '18 at 17:25
  • You can't "use `img` outside". You can only use `img` where it is **available**, which is **inside** (the then handler). That's fundamental to the entire idea of promises and asynchonicity. –  May 12 '18 at 18:32