Home > database >  How to wait until a pdf is generated Javascript
How to wait until a pdf is generated Javascript

Time:10-01

I am using node html-pdf to generate a pdf and nodemailer to automatically send an email containing the pdf every minute using node-cron as demonstrated in the following code:

cron.schedule('* * * * *', () => {
    
    // function to generate scan report using html-pdf
    report.getScanReport();

    // e-mail message options
    let mailOptions = {
        from: {{some_email}},
        to: {{some_email}},
        subject: 'Testing',
        text: 'See PDF attachment',
        attachments: [{
            filename:'test.pdf',
            path: 'C:/Users/test.pdf',
            contentType: 'application/pdf'
        }]
    };

    // Send e-mail
    transporter.sendMail(mailOptions, function(error, info) {
        if (error) {
            console.log(error);
        } else {
            console.log('Email sent: '   info.response);
        }
    });
})

The issue is that generating the pdf takes ~10 seconds or so, so the program tries to send the email before the generated pdf file exists and I then get the error: Error: ENOENT: no such file or directory

Is there a way make sure the pdf is generated before trying to send the email?

CodePudding user response:

Assuming you can modify your getScanReport function, use a Promise. Then in your email function, use async / await to wait for that promise.

(You can click the links to read more about how promises and async / await work if you don't use them very often.)

For example:

report.getScanReport = () => new Promise( 

    //announcePDFReady() is a function we call to resolve our promise

    announcePDFReady => 
        HTMLPDFLibrary. //whatever you called html-pdf
            create( html, options ). //how you're building your pdf
            toFile( 

                'myfilepath...', 

                //this function we pass to toFile() will run when the PDF is ready
                ( err, result ) => {

                    if( err ) announcePDFReady( false );

                    //it's ready, so we'll resolve the promise
                    else announcePDFReady( result );

                }
            )
    
);


//...
//we write 'async' before the cron job function definition
async () => {
    //this is inside the cron job function

    const pdfIsReady = await report.getScanReport();
    //since report.getScanReport() returns a promise,
    //'await' here means our code will stop until the promise resolves.


    if( pdfIsReady === false ) {
        //it failed. Do something? Ignore it?
    } else {

        //pdf is ready. We can send the email
    
        //etc.

    }
}

CodePudding user response:

Assuming you're using this NPM package: https://www.npmjs.com/package/html-pdf-node, you can use the promises that it provides in order to do something after the creation of the PDF file.

You can see it creates a PDF, and then executes additional code. I've edited it a bit to make it easier to understand.

html_to_pdf.generatePdf(file, options).then(() => {
  // this code will execute after the PDF has been generated.
});

If you are using a different package, can you please link it. Thank you.

  • Related