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))
});
});
```
CodePudding user response:
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
CodePudding user response:
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