0

I'm trying to make a simple api with nodejs. However I can't get nodejs to wait for sql queries to finish.

How can I get nodejs to wait for the queries to finish? Am I using await/async wrong?

The goal here is to only return d after the queries have finished.

Database File

const DB_HOSTNAME = "localhost";
const DB_NAME = "testerino";
const DB_PORT = "8889";
const DB_USERNAME = "root";
const DB_PASSWORD = "root";

const mysql = require('mysql');

const con = mysql.createConnection({
  host: DB_HOSTNAME,
  user: DB_USERNAME,
  password: DB_PASSWORD,
  database: DB_NAME,
  port: DB_PORT
});

con.connect(function(err) {
  if (err) throw err
  console.log("Connected to database");
});

async function query(sql){

  var results = await con.query(sql);
  console.log("foo completed")
  return results

}

module.exports = {
  con: con,
  query: query
}

userLogin File

const db = require('../../common/database');

function attemptUserLogin(usernameOrEmail, password){
  var d = {err: [], res: {}};

  console.log("attemptUserLogin");
  const foo = db.query("SELECT * FROM users");
  console.log("This should wait for foo to complete");

  return d;
}

module.exports = {
  attemptUserLogin: attemptUserLogin
};

Results

Connected to database
attemptUserLogin
This should wait for foo to complete
foo completed

^ it's not waiting

Trevor Wood
  • 2,347
  • 5
  • 31
  • 56
  • what is this function is trying to return, i cannot see you are expecting query results to be returned? – Sohan Nov 01 '19 at 09:27

2 Answers2

2

There is no need to use callback with await .Make sure that your con.query() function returns promise ,to you to suceed in this.

async function query(sql){

      var results = await con.query(sql); // the result will be stored in results variable ,once the promise is resolved
    console.log(results) // the query result will be printed here
      return results // the result will be wrapped in promise and returned
    }

The above function will return result only when your promise is resolved and the returned data is stored in results variable.

Now if you want to use above function to get the data,you can do it in two ways

1-Use then.

query().then(data=>{
console.log(data) // this variable data holds the value you returned from above query function

})

2-Call the function with await (but you have to do it in async function)

async function other()
{
let query_result=await query(); // it will return the data from query function above
}

See this answer ,I have discussed all possible cases to query data.

Edit -The issue is with your attemptUserLogin function,you have to make it async as well

async function attemptUserLogin(usernameOrEmail, password){
  var d = {err: [], res: {}};

  console.log("attemptUserLogin");
  const foo = await db.query("SELECT * FROM users"); // use await here
  console.log(foo);// result from query function above

  return d;
}
Shubham Dixit
  • 9,242
  • 4
  • 27
  • 46
  • nice, okay that's returning a promise. Getting closer. How can I keep the function from returning before the promise is complete? – Trevor Wood Nov 01 '19 at 09:15
  • See the updated answer ,the query function won't return a result until the promise is resolved (await) – Shubham Dixit Nov 01 '19 at 09:20
  • I gave it a try but I'm getting an error. ```async function query(sql){ var results = await con.query(sql); return results } async function other(sql){ let queryResult = await query(sql); return queryResult; }``` Could you provide a full snipet of code to make sure I'm implementing this right? – Trevor Wood Nov 01 '19 at 09:38
  • Cannot read property 'length' of undefined. I think something isn't set right – Trevor Wood Nov 01 '19 at 09:40
  • Neither could I. I removed some things and tried something else. I updated the answer, is this what you were saying to do? It is still returning pending – Trevor Wood Nov 01 '19 at 09:49
  • I guess you are bit confused about how this async await thing works .You will get the data from the async query function i have used above ,see if you can console.log result in the query function i mentioned. – Shubham Dixit Nov 01 '19 at 09:52
  • the above code ```async function query(sql){ var results = await con.query(sql); // the result will be stored in results variable ,once the promise is resolved return results }``` returns a pending promise on my end. Should it be returning data? – Trevor Wood Nov 01 '19 at 09:59
  • 1
    Updated the answer please check. – Shubham Dixit Nov 01 '19 at 10:02
  • I updated my question. It seems that `attemptUserLogin` is still proceeding even after `await`. I think I'll just drop nodejs all together and try php or golang for the backend. – Trevor Wood Nov 01 '19 at 10:14
  • 1
    I got your mistake ,wait I am updating my answer – Shubham Dixit Nov 01 '19 at 10:17
  • Oh, super close now. It's returning in order and giving me back the completed object. I just don't know how to get the results out of the object – Trevor Wood Nov 01 '19 at 10:24
  • Do this `JSON.parse(JSON.stringify(foo))`.Please print the result you are getting if that doesn't works – Shubham Dixit Nov 01 '19 at 10:25
  • Getting this error ```(node:29198) UnhandledPromiseRejectionWarning: TypeError: Converting circular structure to JSON at JSON.stringify () at Object.attemptUserLogin (/Users/trevorwood/Desktop/v-gitrepo/VCloudAdminPanelAPI/funcs/user/userLogin.js:11:18) at process._tickCallback (internal/process/next_tick.js:68:7) (node:29198) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: ``` – Trevor Wood Nov 01 '19 at 10:28
  • Possibly there is some error with your query .What does console.log(foo) prints? – Shubham Dixit Nov 01 '19 at 10:29
  • ```SELECT * FROM users``` it's just a simple query – Trevor Wood Nov 01 '19 at 10:30
  • what does console.log(foo) prints? – Shubham Dixit Nov 01 '19 at 10:31
  • https://jsfiddle.net/5az0w28q/ - added it here since it was too long – Trevor Wood Nov 01 '19 at 10:32
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/201713/discussion-between-shubh-and-trevor-wood). – Shubham Dixit Nov 01 '19 at 10:34
1

Revise your execute method like below and put async/await the way I did:

    // put async keyword here
const attemptUserLogin = async (usernameOrEmail, password) => {
    var d = {err: [], res: {}};

    console.log("attemptUserLogin");
    // Put await keyword here
    const foo = await db.query("SELECT * FROM users");
    console.log("This should wait foo.results: ",foo.results);

    return d;
}
Krishan Pal
  • 306
  • 1
  • 3