Reputation: 1
I'm still a bit new to Node.js and Javascript. I know that javascript is asynchronous by nature, but I can't seem to figure out how to solve this problem. I tried using Promises but that didn't help for this particular case (or maybe I don't know how promises work).
Inside my getChilds() function, I make a search by id in my mongo database and I push the found object to an array called childObjects that I receive by parameter in the getChilds() function.
The object is found and added to the childObjects array. I use console.logs to check that it works. The problem is that when we exit the function, the value for childObjects is undefined.
My getChilds() function:
function getChilds(id, childObjects, res) {
return new Promise((resolve, reject) => {
Item.findById(id, function (err, item) {
if (err) {
console.log("There's no corresponding item for that id!");
return (res.send(err));
}
console.log("CHILD ITEM:" + item);
childObjects.push(item);
console.log("chiild ojects: " + childObjects);
// return childObjects;
// res.send(childObjects);
// return childObjects;
// res.send(item);
resolve(item);
// childObjects.push(item);
});
});
}
Thank you for your help!
Upvotes: 0
Views: 44
Reputation: 11
You are totally right. You are facing two this problem because you used Promise. With Promise, Your code becomes to Non-Blocking code.
I can suggest two solutions to solve this issue.
Scope:
let childObjects;
function getChilds(id, res) {
return new Promise((resolve, reject) => {
...
});
}
Return the value:
function getChilds(id, childObjects, res) {
return new Promise((resolve, reject) => {
...
resolve({item: item, childObjects: childObjects);
});
});
}
Upvotes: 0
Reputation: 1055
You shouldn't pass childObjects
in.
You have two options: either you define childObjects
at the same level of getChilds
. So for instance if you can call this.getChilds
then the childObjects
array should exist at this.childObjects
. Or you resolve(item)
and in the callback of the function, where you did this.getChilds(id).then(
, you push to the childObjects
living in the parent.
Upvotes: 0
Reputation: 350310
You should not pass childObjects
as argument, nor res
. Instead collect the item
into childObjects
outside of the function:
function getChilds(id) {
return new Promise((resolve, reject) => {
Item.findById(id, function (err, item) {
return err ? reject(err) : resolve(item);
});
});
}
Use Promise.all
to get your childObjects
array:
// Somehow you will get an array of id values, maybe like this:
const childs = item.childs;
// Create promises for each of them
const promises = childs.map(getChilds);
// Promise.all will await all the promises to resolve, putting all items in an array:
Promise.all(promises).then(childObjects => {
console.log(childObjects);
res.send(childObjects);
}).catch(err => {
console.log('Error occurred', err);
res.send(err);
});
Note that the plural of "child" is "children" not "childs" ;-)
Upvotes: 1