I’ve got an endpoint in my Application that is supposed to fetch data from a MongoDb Database and return the results to the Client. However, before my for(){} loop finishes execution and an empty array ends up getting sent. How do I change my Code where I can send the Array only when it’s completely populated.
Code Below:
app.get("/check/classes/usercart", (req, res) => {
if(req.session.user){
UserCart.findOne({userId: req.session.user._id}).lean().exec()
.then((foundUserCart)=>{
if(foundUserCart){
console.log("Found user in the UserCart Collection", foundUserCart);
console.log("Printing User's classCart", foundUserCart.classCart);
//return res.json({classes: foundUserCart.classCart});
const classesArray = foundUserCart.classCart;
let arrayToSend = [];
for(let i = 0; i < classesArray.length; i++){
Classes.findById({_id: classesArray[i]}).lean().exec()
.then((foundClass)=>{
console.log("Class Found", foundClass);
arrayToSend.push(foundClass);
console.log("Printing ArrayToSend", arrayToSend);
})
.catch((error)=>{
console.log("Error performing findById", error);
return res.json({msg: "Server Error"});
});
}
//return arrayToSend;
//This get's executed before my for loop finishes. I'm new to NodeJs and
//the whole asynchronous cycle
return res.json({classes: arrayToSend});
}else{
return res.json({msg: "No records found for this user"});
}
})
.catch((error)=>{
console.log("Error performing UserCart.find() operation", error);
return res.json({msg: "Server Error"});
});
}else{
return res.redirect("/");
}
});
Please could somebody kindly give me some suggestions? Been stuck on this for a while now. Thanks.
Update:
So I got around this by doing the following:
Classes.find({'_id': {$in: classesArray}})
.then((foundRecords)=>{
console.log("Found records", foundRecords);
return res.json({classes: foundRecords});
}).
catch((error)=>{
console.log("Error here", error);
});
This just returns the entire array of records. Probably not the cleanest solution. Could somebody tell me how to do this entire function using Async Await?
3
Answers
Using Promise.all
Bonus: Rewrite the above using Async/await
You can make your query with multiple IDs in a single operation. That would eliminate the need for the for loop.
Use async/await to clean your code. Your final controller will look like this