Search code examples
javascriptjquerypromisehtml2canvas

Calling two Html2Canvas calls using jQuery.when()


I am trying take screenshot of two divs using html2canvas. I am trying to achieve this using promises such that once both html2canvas calls are finished, I run my AJAX call in then().

I don't know where I am going wrong. I am getting error saying:

Uncaught TypeError: canvas.toDataURL is not a function

$.when(
  html2canvas(div_elem1),
  html2canvas(div_elem2)
).then(function(canvas, canvas2) {
  myImage1 = canvas.toDataURL();
  //tried with this too, myImage1 = canvas[ 0 ].toDataURL();
  myImage = canvas2.toDataURL();
  var data = {
    action: 'save_data',
    a: $.extend({}, a),
    b: $.extend({}, b),
    base64data: {
      x: myImage,
      y: myImage1
    },
  };

  $.post(ajaxurl, data, function(response) {

  });
});

I am using html2canvas 1.0.0-alpha.12

Edit: It works if I do this way below. But this will take a longer time comparatively

html2canvas(div_elem1).then(function(canvas) {

            myImage1 = canvas.toDataURL();

            html2canvas(div_elem2).then(function(canvas2) {

                    myImage = canvas2.toDataURL();

                      //ajaxcall...

Solution

  • Jquery's .when method in version below 3 was not compatible with Promises, only with jQuery's Deferred objects.

    $.when(Promise.resolve('done')).then(console.log);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

    You need to update your jQuery version to higher than v3 in order to be able to pass Promises to it and use your code as is.

    $.when(Promise.resolve('done')).then(console.log);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>

    But note that you don't really need to rely on jQuery here, html2canvas requires the browser to support javascript Promises, so you can very well just use the native Promise.all method:

    Promise.all([
      Promise.resolve('first'), // html2canvas(...),
      Promise.resolve('second') // html2canvas(...)
    ]).then(function(canvases) {
      var canvas = canvases[0],
        canvas_1 = canvases[1];
      console.log(canvas, canvas_1);
    });