JavaScript - Wait until all array.push() are complete before returning function [duplicate]

Multi tool use
JavaScript - Wait until all array.push() are complete before returning function [duplicate]
This question already has an answer here:
I have written a function that loops over an object and uses array.push(XYZ)
to append the value (XYZ
) to the array (array
). After the loop is complete the function returns a promise. When I use myFunction().then(function(response) { console.log(response[0])})
, I get undefined
in the console. When I type in console.log(response[0])
in the console, I get the correct value. What am I doing wrong? I think that it is taking time to push the value into the array but I am not 100%. Any help will be appreciated.
array.push(XYZ)
XYZ
array
myFunction().then(function(response) { console.log(response[0])})
undefined
console.log(response[0])
My Code (I have not included the code defining db
but it is not important as getting the info from the database is working fine.)
db
function getChild(uid) {
promise = db.collection("users").doc(uid).get().then(function(doc) {
output = ;
val = doc.data();
studentsObj = val.students;
studentsObj.forEach(function(student) {
db.collection("students").doc(student).get().then(function(res) {
varl = res.data()
output.push(varl);
});
});
return output;
});
return promise;
};
getChild("parentUserID").then(function(reply) {
got = reply;
console.log(got);
});
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
push
db.collection("students").doc(student).get()
1 Answer
1
Asynchronous operations inside a forEach
won't be chained with the outer Promise chain - use map
instead to create an array of Promises
, and then you need to return a Promise.all
so that the promises generated by each studentsObj
are properly chained. You should also try to avoid implicitly creating global variables - use const
instead.
forEach
map
Promises
Promise.all
studentsObj
const
Try something like this:
const getChild = (uid) => (
db.collection("users").doc(uid).get()
.then(doc => {
const { students } = doc.data();
return Promise.all(students.map(student => (
db.collection("students").doc(student).get()
.then((res) => res.data())
)))
})
);
Or, using async
functions instead to make the code a bit flatter:
async
const getChild = async (uid) => {
const doc = await db.collection("users").doc(uid).get();
const { students } = doc.data();
return Promise.all(students.map(async (student) => {
const res = await db.collection("students").doc(student).get();
return res.data();
)));
};
Can this be executed using
getChild("parentUserID")
?– B. Sommer
Jul 1 at 20:48
getChild("parentUserID")
Yes, calling
getChild
will now return a Promise
that resolves after all asynchronous operations are done– CertainPerformance
Jul 1 at 20:49
getChild
Promise
If it solved your problem, consider marking the answer as Accepted to indicate that the issue is resolved
– CertainPerformance
Jul 1 at 21:24
It's not the time to call
push
, its the time to calldb.collection("students").doc(student).get()
. That's asynchronous. You will return the empty output before it returns.– Mark Meyer
Jul 1 at 20:40