Execute function after DOM is rendered in svelte

Viewed 1746

I need to run function that will emit event after DOM is fully updated. I combine Svelte with Electron.js. This page is used as PDF generator, it loads data from primary process, then it updates itself and finally notifies main process that everything is loaded and main process screenshots contents of this (PDF process). So code:

PDF process renderer:


    onMount(() => {
        // Asks for the data, emits event
        ipc.send('PDFWindowReady');
    });

    ipc.on('PDFLoadContent',(event,data)=>{
        // Gets the data, event listener
        const content = data.data;

        // Assigns the data to a particular variable
        contractorEnterprise = content.contractor.enterprise;
        contractorAddress = content.contractor.street;
        contractorCity = content.contractor.city;

        //long list of assignments

        output = data.output;
        // Renders empty PDF, that means, that DOM has not re-rendered yet
        // I need to ensure that it has, then execute function below
        //ipc.send('makePDF',data.output)
    });

    beforeUpdate(async () => {
        // This doesn't work, empty PDF
        await tick();
        if (output) {
            await tick();
            ipc.send('makePDF',output);
            console.log(output);
        }
    });

    /*
    afterUpdate(() => {
        // This neither
        if (output) {
            ipc.send('makePDF',output)
        }
    });
    */

    ipc.on('PDFCreated',()=>{
        // after PDF is generated, window will be closed
        /* I even tried timeouts, but that is unreliable and could cause unloaded content
           on big data load */
        //setTimeout(() => {
        window.close()
        //},1000);
    });

electron.js (main.js):

ipcMain.on('makePDF', (event,aux)=>{
    const pdfPath = path.join(appRoot.pdfPath,aux.file);
    const content = BrowserWindow.fromWebContents(event.sender);
    content.webContents.printToPDF({
        pageSize: "A4",
        landscape: false
    }).then(data => {
        fs.writeFile(pdfPath, data, (error) => {
            event.sender.send('PDFCreated');
            if (error) throw error;
            new Notification({
                title: 'PDF je hotové',
                body: `Exportovanie dodacieho listu do ${pdfPath}.pdf bolo ukončené.`
            }).show();
            shell.openExternal(`file://${pdfPath}`);
            console.log(`New delivery note:${pdfPath}`);
        })
    }).catch(error => {
        console.log(error.message)
    })
});

//triggered by primary process
ipcMain.on('openPDFWindow',(event,data)=>{
    //opens new invisible browser window
    fpt.createPDFWindow();
    ipcMain.once('PDFWindowReady',(event)=>{
        //as soon as is window ready event is emmited
        event.sender.send('PDFLoadContent',data);
    });
});

Output of line 76, console.log(output):

Object containing name of output file

So as you can see, none of my attempts to send event after page is loaded is working. The problem is that it renders empty PDF. Previously I used jQuery and I solved it with timeouts, but that was stupid error prone solution. I need to run this function after everything is rendered:

ipc.send('makePDF',output)

The problem is that it renders empty PDF, it seems like page has not re-rendered and screenshot was taken too early. Is there any reliable solution?

0 Answers
Related