Reputation: 1123
So I have an async function which takes an array of custom objects as an argument, then loop through each of those objects and get some data from the firestore. The data from Firestore is converted to another custom object and added to another to an array of custom objects. The length of these objects is returned by the function.
async function getCompsReceived(theInterestedPeople: InterestedPerson[]) {
const whatsNewObjects: WhatsNewObject[] = []
theInterestedPeople.forEach(async (person) => {
const documentsSnapshot = await
db.collection('Users').doc(person.uid).collection('complimentsReceived')
.orderBy('receivedTime', 'desc')
.limit(documentLimit)
.get()
if (documentsSnapshot.empty) {
console.log(`${person.userName} has no compsReceived`)
return
}
await documentsSnapshot.forEach((newCompReceived: { receiverUid: string; receiverUserName: string;
complimentsReceivedContent: string | null; hasImage: boolean | null; senderUid: string | null;
senderUserName: string | null; noOfLikes: number | null; receivedTime: number | null;
complimentId: string | null} ) => {
//Add each new Compliment to the WhatsNewObjects Array
const whatsNewDoc = new WhatsNewObject(
newCompReceived.receiverUid,
newCompReceived.receiverUserName,
true,
newCompReceived.complimentsReceivedContent,
newCompReceived.hasImage,
newCompReceived.senderUid,
newCompReceived.senderUserName,
newCompReceived.noOfLikes,
newCompReceived.receivedTime,
newCompReceived.complimentId,
'PERSON_COMPLIMENT_RECEIVED'
)
whatsNewObjects.push(whatsNewDoc)
})
console.log(`length of whatsNewObjects after adding ${person.userName}'s compsReceived is
${whatsNewObjects.length}`)
})
console.log(`returning the length of WhatsNewObjects at getCompsReceived which is ${whatsNewObjects.length}}`)
return whatsNewObjects.length
}
The problem is this function always returns 0 and with the log statements printed at Firebase console, I see that the body of the function is being executed after the function has already returned a value which is a Promise of type number.
Can someone help me in How do I make the function wait for the body to be executed before returning the whatsNewObjects.length ?
Upvotes: 0
Views: 269
Reputation: 848
The problem is related to forEach
it actually run async even if you use async/await
in callback function .
You can solve this problem by simply changing forEach
to any kind of for
iterators.
for (let index = 0; index < theInterestedPeople.length; index++) {
const person = array[index];
....your code
}
// or
for (const person of theInterestedPeople) {
}
// or
Upvotes: 1
Reputation: 7862
You shouldn't use forEach
for iterating async code since it doesn't await
. It will just fire-and-forget. Use for..of
instead:
async function getCompsReceived(theInterestedPeople: InterestedPerson[]) {
const whatsNewObjects: WhatsNewObject[] = []
for (const person of theInterestedPeople) {
const documentsSnapshot = await db.collection('Users').doc(person.uid).collection('complimentsReceived')
.orderBy('receivedTime', 'desc')
.limit(documentLimit)
.get();
if (documentsSnapshot.empty) {
console.log(`${person.userName} has no compsReceived`)
return;
}
documentsSnapshot.forEach((newCompReceived: {
receiverUid: string; receiverUserName: string;
complimentsReceivedContent: string | null; hasImage: boolean | null; senderUid: string | null;
senderUserName: string | null; noOfLikes: number | null; receivedTime: number | null;
complimentId: string | null
}) => {
//Add each new Compliment to the WhatsNewObjects Array
const whatsNewDoc = new WhatsNewObject(
newCompReceived.receiverUid,
newCompReceived.receiverUserName,
true,
newCompReceived.complimentsReceivedContent,
newCompReceived.hasImage,
newCompReceived.senderUid,
newCompReceived.senderUserName,
newCompReceived.noOfLikes,
newCompReceived.receivedTime,
newCompReceived.complimentId,
'PERSON_COMPLIMENT_RECEIVED'
);
whatsNewObjects.push(whatsNewDoc);
})
console.log(`length of whatsNewObjects after adding ${person.userName}'s compsReceived is ${whatsNewObjects.length}`);
}
console.log(`returning the length of WhatsNewObjects at getCompsReceived which is ${whatsNewObjects.length}}`);
return whatsNewObjects.length;
}
Upvotes: 2