I’m new to Node.js and having difficulty working with async/await model. The issue I’m having is with nested function calls returning data in an async/await method, I always get 'undefined'
. My functions structure is like this:
const findCustomerOrder = async (id) => { const orders = await Order.find({custoemrId:id}) .then(async (order) => { if(order) { const products = await findProductsByOrderId(order._id) .then(async (result) => { for(const r in result){ console.log("Product ID: ", result._id); } }); } else console.log("order not found"); }); } const findProductsByOrderId = async (id) => { try{ const products = await Products.find({orderId:id}, (error, data) => { if(error) console.log(error); else return data; }); } catch(err){ return 'error!!'; } }
I understand that if the top-level call is async/await then all the nested calls should be awaited as well that I’ve tried to do.
What am I doing wrong here?
Advertisement
Answer
Get rid of all the then
, and also of the callback in the DB query. Use only await
. It will make the whole code a lot easier to reason about and it should also solve your issue as part of the restructuring.
In the example below I also added a loop over the orders, because you are fetching all orders, as array, but then your code was behaving as if it got only one. I also fixed the products loop.
However, the way you fetch products doesn’t seem to be right anyway, see my comment below. I didn’t fix it because I don’t know how your database structure looks, so I don’t know what the right way would be.
async function findCustomerOrder (id) { const orders = await Order.find({ customerId: id }) for (const order of orders) { console.log(`Order ID: ${order._id}`) const products = await findProductsByOrderId(order._id) for (const product of products) { console.log(`Product ID: ${product._id}`); } } } async function findProductsByOrderId (id) { // Note: I don't think this is right. It seems to find all // products with the given ID - which will always be one - // and that ID would be the _product_ ID and not the order ID. return await Products.find({ _id: id }) }
Preemptive comment reply: The return await
is intentional, and this is why.