Reputation: 59
I'm new in writing typescript with async-await but I retrieved all discounts, check if active or expired, if expired get all discount products then print its id's on the response, the problem I can't handle nested promises and get ids of discounted products to display in response
exports.terminateDiscount = functions.https.onRequest(async (req, res) => {
try {
const discountSnapshots = await admin.firestore().collection("Discounts").get();
const promises = [];
const today = Date.now();
discountSnapshots.forEach(async discountSnapshot => {
const startDate = +discountSnapshot.data().startDate.toMillis();
const endDate = discountSnapshot.data().endDate;
if (today > startDate && endDate !== null && today > endDate.toMillis()) { // discount expired
promises.push(discountSnapshot.id); // print discount id only
const discountProducts=await admin.firestore().collection("Products").where("discountId", "==", discountSnapshot.id).get();
discountProducts.forEach(product => {
promises.push(product.id); // products id's not added in promises :(
});
}
});
res.send(await Promise.all(promises));
} catch (error) {
}
});
Upvotes: 0
Views: 163
Reputation: 16127
It's so hard to use async/await
with .forEach
. In simple, .forEach
calls a callback with each item of array, and it always is a sync
process. This mean, you will never wait until const discountProducts = await admin.firestore()...
finish, you return immediate after call discountSnapshots.forEach...
.
Promise.all
just working fine if you give it a promises array, in your code, you pass a strings arrays (I think discountSnapshot.id
is a string) to Promise.all
, in this case it will return "original" input - strings array.
I suggest use Array.map
in this case, .map
function returns a array, we make it to return a promises array, then just wait until all of promises finish.
exports.terminateDiscount = functions.https.onRequest(async (req, res) => {
try {
const discountSnapshots = await admin.firestore().collection("Discounts").get();
const today = Date.now();
const ids = []; // to store discount id or products id or both ????
const promises = discountSnapshots.docs.map(async (discountSnapshot) => {
const startDate = +discountSnapshot.data().startDate.toMillis();
const endDate = discountSnapshot.data().endDate;
if (today > startDate && endDate !== null && today > endDate.toMillis()) { // discount expired
ids.push(discountSnapshot.id); // print discount id only ???
const discountProducts = await admin.firestore().collection("Products").where("discountId", "==", discountSnapshot.id).get();
discountProducts.forEach(product => {
ids.push(product.id); // products id's ??? "print discount id only"
});
}
});
await Promise.all(promises); // wait until we fill the ids array, the ids has been filled.
res.send(ids);
} catch (error) {
}
});
Upvotes: 2