My mongoose schema is
skills : [
{
name : {type : String},
count : {type :Number, default:0}
}
]
and i am firing the update query using for loop as i want to update array of documents and my query is
for(var i=0;i<array.length;i++){
Talent.update({userName : userName}, {$addToSet: {skills :{$each: [{name : array[i]}]}}},callback);
}
here callback gets return for every update query is fired. i want to make callback with database result only once when for loop gets completed. What should i do?
I think you need something like this:
var update = function(callback) {
var result = {};
var len = array.length;
var done = 0;
for (var i = 0; i < len; i++) {
Talent.update({
userName: userName
}, {
$addToSet: {
skills: {
$each: [{
name: array[i]
}]
}
}
}, function(err, talent) {
result[i] = {
err: err,
talent: talent
};
done++;
if (done === len)
callback(result);
});
}
};
Now you can just call
update(function(result) {
// Your code here.
};
Anyway I didn't test it, so it may have some problems.
This really looks like you are asking to modify one document only, but where you are presently looping updates you do not need to do that.
Also you are asking for the modified result, which actually belongs to methods like .findOneAndUpdate(), as that form returns the modified document. The .update() form which can be applied to multiple documents and therefore does not return the modified contents in the result:
So it really looks like rather than looping, then all you need to do is "re-shape" your input array:
var array = ["Tennis","Football"];
array = array.map(function(x) {
return { "name": x };
});
// array is now [{ "name": "Tennis" }, { "name": "Football" }]
Talent.findOneAndUpdate(
{ "userName": userName },
{
"$addToSet": { "skills": { "$each": array } }
},
function(err,doc) {
if (err) throw err;
// doc contains all array members added
console.log( JSON.stringify( doc, undefined, 4) );
callback(); // Your outer callback
}
);
The $each modifier takes an array argument in the last case, so it is just a matter of re-shaping your input arguments in the original array to match the structure expected when updating the actual document.
There are other ways of dealing with performing the looping in series, but it would seem that in this case you do not need it.