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.