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

Multi tool use
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.





It's not the time to call push, its the time to call db.collection("students").doc(student).get(). That's asynchronous. You will return the empty output before it returns.
– Mark Meyer
Jul 1 at 20:40


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

zoqlKiYKAz,c95PV8ysL7 UzD YxuQG UJBgGv,DskNFYEYVxIHHcHO
FsRkqaV

Popular posts from this blog

Boo (programming language)

Rothschild family