In my nodejs app I need to write data into my mysql database, then create a PDF file out of this data and then send this file as an attachment in an email.
The two functions generatePDF() and sendMail() are async function and, therefore, return a promise. I am calling these two functions in connection.query(). I know that I have to use promises in order to run generatePDF() first before sendMail() is executed but I am unable to get this working.
I tried to use, without success :
await generatePDF()
andawait sendMail()
(with and withoutasync
beforefunction
) but this throws an errorSyntaxError: await is only valid in async functions and the top level bodies of modules
generatePDF().then(sendMail())
but they are executed asynchronouslyPromise.all([generatePDF(),(sendMail()])
but they are executed asynchronouslyi
For clarity, I only post parts of the code.
const mysql = require('mysql2'); // I tried mysql2/promise as well app.post('/HSF/calculator/register', async function (request, response) { var params = request.body; //console.log('params:',params); connection.query('INSERT INTO client_data SET ?', params, function (error, results, fields) { if (error) { throw error; } else { console.log('after .query(), before createOutputFile') var createOutputFile = ` SELECT CONCAT("{",'"id":', JSON_OBJECT( "clientID",clientID,"name",name,"email",email,"age",age,"currentWeight",currentWeight,"weightUnit",weightUnit,"goalWeight",goalWeight, "height",height,"goalDate",goalDate,"mealsPerDay",mealsPerDay,"activityLevel",activityLevel,"eatingStyle",eatingStyle,"nutritionalRatio", nutritionalRatio,"workoutLevel",workoutLevel) ,"}") AS json FROM HerSoulFit.client_data WHERE fileCounter = ${params.fileCounter} INTO OUTFILE '/var/lib/mysql-files/data_${params.fileCounter}.json';` connection.query(createOutputFile, (error, results) => { if (error) { throw error } else { response.end(JSON.stringify(results)); } }) await PDF.generatePDF(params.fileCounter) await nodemailer.sendMail(params.name, params.email, params.fileCounter) // does not work: PDF.generatePDF(params.fileCounter).then(nodemailer.sendMail(params.name, params.email, params.fileCounter)) }); }); ```
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
the async keyword is in the wrong place. Remove it and change this line :
connection.query('INSERT INTO client_data SET ?', params, function (error, results, fields) {
to
connection.query('INSERT INTO client_data SET ?', params, async function (error, results, fields) {
I confirm it will be better to call sendMail when generatePDF resolve
Method 2
I believe you would have to change this line:
connection.query('INSERT INTO client_data SET ?', params, function (error, results, fields)
to this line:
await connection.query('INSERT INTO client_data SET ?', params, async function (error, results, fields)
This would await the connection for the post call and inside the query you can then await the anonymous function.
Just a guess
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0