Reputation: 643
I am using findOneAndUpdate in a forEach loop to create/update multiple entries.
I would like it to return an array of all the object id's it has created or updated.
During the loop, I can see it adding data to the array, but one it leaves the loop, the array is empty.
Should the array not be populated?
here is my code.
var softwareArray = ["Software1","Software2","Software3"],
updatedArray = [];
softwareArray.forEach(function(software){
Software.findOneAndUpdate(
{
Name: software
},
{
Name: software
},
{upsert:true},
function(err, rows){
updatedArray.push(rows._id);
console.log(updatedArray); //This has data in it....
}
);
});
console.log(updatedArray); //This has no data in it...
Edit: Updated with my working changes for Thiago
var softwareArray = ["Software1","Software2","Software3"],
updatedArray = [];
loopSoftware(softwareArray, function(updatedArray){
console.log(updatedArray);
//carry on....
}
function loopSoftware(input, cb){
var returnData = [];
var runLoop = function(software, done) {
Software.findOneAndUpdate(
{Name: software},
{Name: software},
{upsert:true},function(err, rows){
returnData.push(rows._id);
done()
}
);
};
var doneLoop = function(err) {
cb(returnData);
};
async.forEachSeries(input, runLoop, doneLoop);
}
Upvotes: 1
Views: 3759
Reputation: 63159
I decorated your code to make you see when what is happening:
var softwareArray = ["Software1","Software2","Software3"],
updatedArray = [];
// TIMESTAMP: 0
softwareArray.forEach(function(software){
// TIMESTAMP: 1, 2, 3
Software.findOneAndUpdate(
{
Name: software
},
{
Name: software
},
{upsert:true},
function(err, rows){
// TIMESTAMP: 5, 6, 7
updatedArray.push(rows._id);
console.log(updatedArray); // This has data in it....
// want to use the result?
if (updatedArray.length == softwareArray.length) {
console.log(updatedArray);
}
}
);
});
// TIMESTAMP: 4
console.log(updatedArray);
Upvotes: 1
Reputation: 41440
Of course this will happen - just like any other networking on Node, it's asynchronous!
This means that the callback you specified for your findOneAndUpdate
operation have not run yet when it reaches the console.log(updatedArray);
code.
Take a look at Q for working around this common problem.
Upvotes: 0