Essentially, I have an object with string keys and values (ex. {“michigan”:”minnesota”}). I’m trying to loop through all of these key value pairs and make a query from my database, and add the result to a list, which will then be what is returned to the front end.
var return_list = [] Object.keys(obj).forEach(function(key){ const state1 = key; const state2 = obj[key]; const sql_select = 'SELECT column1,column2 from database WHERE state = ? OR state=?'; db.query(sql_select,[state1,state2], (err,result) => { return_list.push(result); }); })
This is what I have in simplest terms, and would like to send return_list back to the front end. The problem I’m running into is I can console.log the result within db.query call, but I can’t push the result to the list or call it anywhere outside of the query. I’m fairly new to both front end and back end development, so any possible ideas would definitely be helpful!
Advertisement
Answer
The problem is that the forEach
returns void.
So you can’t wait for the asynchronous code to run before you return it.
When we’re dealing with an array of promises such as db queries ( like in your case ) or API calls, we should wait for every one of them to be executed.
That’s when we use the Promise.all
Try doing it like this:
const queryResults = await Promise.all( Object.keys(obj).map(async (key) => { const state1 = key; const state2 = obj[key]; const sql_select = 'SELECT column1,column2 from database WHERE state = ? OR state=?'; return new Promise((resolve, reject) => db.query(sql_select,[state1,state2], (err, result) => { if (err) return reject(err) else return resolve(result) }) ) }) ) console.log('queryResults', queryResults) // now you give this queryResults back to your FE
Small tips for your fresh start:
- never use var, try always use const or if needed, let.
- try always use arrow functions (
() => {...}
) instead of regular functions (function () {...}
), It’s hard to predict which scope this last one is using