Mahdiur Rahman
Mahdiur Rahman

Reputation: 25

Database Querying function not running asynchronously

So I created a function in my node server which takes in a query string, runs it on my db, and returns the results. I then wanted to use my function asynchronously using async await throughout my routes instead of having nested query within, nested query, within nested query etc.

So here is the code:

 const runQuery = queryString => {
    console.log("...runQuery")
    db.query(queryString, (error, results, fields) => {
        if (error) {
            console.log("runQuery: FAILURE");
            return error;
        }
        else {
            console.log("runQuery: SUCCESS");
            return(results);
        }
    })
}

register.post("/", async (req, res) => {
    console.log(req.body);
    const results = await runQuery("select * from test1");
    res.send(results);
})

The database should have 3 entries, but unfortunately, it returns nothing. Meaning results is an empty variable when it is sent, meaning JS never properly waits for it to capture the db results. How can I use my function asynchronously, and how is this even feasible?

Upvotes: 0

Views: 54

Answers (1)

Anuj Pancholi
Anuj Pancholi

Reputation: 1203

It seems your function "runQuery" does not return a promise, in fact, it's not returning anything. You are using "return" in the callback of the db.query function, not the function "runQuery" itself.

Since runQuery is performing an asynchronous operation, the result ought to be resolved via a promise (which is what the "await" in your request handler is looking for).

I'm not exactly sure but it seems you are using MySql, and I could not find anything on the npm page of the mysql package regarding the query being promisified, so we'll promisify it ourselves:

const runQuery = (queryString) => new Promise((resolve,reject) => {
    console.log("...runQuery")
    db.query(queryString, (error, results, fields) => {
        if (error) {
            console.error("runQuery: FAILURE");
            reject(error);
        } else {
            console.log("runQuery: SUCCESS");
            resolve(results);
        }
    })

})

register.post("/", async (req, res) => {
    console.log(req.body);
    try{
        const results = await runQuery("select * from test1");
        res.send(results);
    }catch(e){
        console.error(`ERROR THROWN BY runQuery:`,e);
        res.status(500).send({
            message: e.message || "INTERNAL SERVER ERROR"
        })
    }
})

Note that if an error occurs, our promisified function will reject the error and it will NOT be stored in the "results" variable in our request handler. Instead, an error will be thrown which needs to be handled. Therefore, it is always a good practice to put any async/await calls inside a try/catch.

Upvotes: 1

Related Questions