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?