Search code examples
javascriptvue.jshtml2canvas

JS - Method executes last even though it's invoked first


I have these two functions, where "form" is the name of the Vue object:

form.sizeChartAsImage();
form.setSizeChart();

This is the code of said functions:

setSizeChart: function () {
            for (i = 0; i < this.columns.length; i++) {
                this.product.size_chart.push({
                    position_x: 0,
                    position_y: i,
                    value: this.columns[i],
                })
                for (j = 0; j < this.data.length; j++) {
                    for (var key in this.data[j]) {
                        if(key === this.columns[i]) {
                            this.product.size_chart.push({
                                position_x: j+1,
                                position_y: i,
                                value: this.data[j][key],
                            })
                        }
                    }
                }
            }
        }

sizeChartAsImage: function() {
            html2canvas($("#size-chart").get(0)).then(canvas => {
                canvas.toBlob (blob => {
                    var sizechartImg = document.createElement('img');
                    url = URL.createObjectURL(blob);
                    sizechartImg.src = url;
                    this.product.size_chart_image = sizechartImg;
                    debugger;
                }, 'image/png');
            }) 
        }

Nevertheless, the second function get executed first (debugger enters first) and then the rest of the code runs; the form is submitted, and lastly, sizeChartAsImage() gets executed, causing no effect (since the form was submitted with "size_chart_image" as null)

This is what I'm trying to render, and it does generate the image.

<demo-grid
:data="data"
:columns="columns"
id="size-chart">
</demo-grid>

Could it be because it's a Vue component? Performance issues? Or do I need to use a callback maybe?


Solution

  • It's because html2canvas($("#size-chart").get(0)) is returning a promise (maybe just a thenable), which is an async call.

    So sizeChartAsImage will run, and html2canvas($("#size-chart").get(0)) will execute. While the script is waiting for that to return it'll continue to setSizeChart function and run it. And then it'll return to the code within the then(canvas => callback.

    You could either call setSizeChart at the end of the callback. Or, if you're using ES2017 or greater, you could re-write sizeChartAsImage to be async and await it.