Wait for html2canvas to finish, before showing “successful” message

(Repost from serverfault)

I’m pretty new to JavaScript development.

I have a PHP/HTML webpage where users can edit things and once they’re done, they click on “Save” and it saves changes to the database. This works well, but what I implemented, is html2canvas to save a rendered image of the current state, to display it on another page.

My problem is: Rendering and saving takes about 15 seconds right now until the image file is saved. If users close their tab before this is done, of course the rendering breaks. So I decided to display a message “Please wait for rendering”, that closes once the rendering is done.
But I can’t manage to wait until the rendering is done – I have read lots about promises, async, await and stuff but yet I don’t fully understand that functionality.

Here’s my code:

const saveButton = document.getElementById('saveButton');
saveButton.addEventListener('click', saveChanges); 
function saveChanges() {  
    // here is the code for saving data to database ...
    // then the image will be rendered  
    console.log('Start image generating')
    showSaveMessage('Öffentliche Ansicht wird generiert...'); // This creates a message box
    // setTimeout is needed, because otherwise somehow, the rendering is missing texts etc.
    setTimeout(() => {
        html2canvas(document.getElementById('map'), {
            onclone: function(document) {
                // do some CSS changes before rendering
                });
            },
            scale: 2,
            useCORS: true,
        }).then(canvas => {
            console.log('Starting to convert');
            const imgData = canvas.toDataURL('image/png');
            fetch('sources/saveimage.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ imageData: imgData })
            });
            console.log('Conversion done');
        });
    }, 200);
    hideSaveMessage(); // This closes the message box
}

Currently, the message box is closed immediately after opening it, so it doesn’t actually wait for rendering and saving the image. I also tried adding a .then after fetch, but it closes the message within 1-2 seconds, while PHP needs 10-15 seconds to actually finish the image saving.

My PHP is pretty easy:

<?php

$data = file_get_contents('php://input');
// error_log($data);
$image = explode('base64,',$data); 
file_put_contents('images/glencore/rendered.png', base64_decode($image[1]));

?>

Maybe some of you are kind enough to solve this and explain to me 🙂