Nodejs with mysql2, promise functions in are not excuted in order

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() and await sendMail() (with and without async before function) but this throws an error SyntaxError: await is only valid in async functions and the top level bodies of modules
  • generatePDF().then(sendMail()) but they are executed asynchronously
  • Promise.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

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x