Reputation: 420
I am creating an array JSONs with some test names and questions that are fetched from a database as follows:
db.all(sql_instruction, [], (err, rows) => {
if (err) {
console.log(err)
}
rows.forEach(test=>{
let test_name = test.test_name;
let question_array = [];
sql_instruction = `SELECT * from questions where test_id = ?`;
db.all(sql_instruction, [test.id], (err, rows) => {
if (err) {
console.log(err);
}
rows.forEach(question=> {
question_array.push(question);
});
test_array.push(JSON.stringify({'test_name':test_name, questions:question_array}));
});
});
});
If I try to access the variable 'test_array' outside the first db.all(), I would get an empty array because the async nature of the function.
What would be the best way to 'wait' for the completion of the 'test_array' variable to use it further in the application?
Upvotes: 1
Views: 2754
Reputation: 5411
We can use Promise and async/await sugar syntax to make an asynchronous code looks like synchronous one. In the code below, I create a function getAllPromise
to wrap the db.all
method in a Promise. Then I can "wait" my getAllPromise
function.
function getAllPromise(query, params) {
return new Promise((resolve, reject) => {
db.all(query, params, (err, rows) => {
if(err) {
// case error
reject(err);
}
// "return" the result when the action finish
resolve(rows);
})
})
}
async function getTestWithQuestions() { // your code
try {
let sql_instruction = ""; // your SQL query;
const rows = await getAllPromise(sql_instruction, []);
let test_array = [];
for(let i = 0; i < rows.length; i = i + 1) {
const test = rows[i];
let test_name = test.test_name;
let question_array = [];
sql_instruction = `SELECT * from questions where test_id = ?`;
const question_rows = await getAllPromise(sql_instruction, [test.id]);
question_rows.forEach(question=> {
question_array.push(question);
});
test_array.push(JSON.stringify({'test_name':test_name, questions:question_array}))
}
return test_array;
} catch(error) {
console.log(error);
throw error;
}
}
// using
// you need to add the keyword "async" in the function that call getTestWithQuestions, then :
const testWithQuestions = await getTestWithQuestions(); // testWithQuetions is `test_array`
// if you don't want to add async keyword, then :
getTestWithQuestions()
.then(testWithQuestions => console.log(testWithQuestions))
.catch(error => console.log(error));
You can find more information about callback, Promise and async/await here
Upvotes: 3