0

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?

2
  • The general problem seems quite clear, but what is not clear here is usage of a "count" field under the documents in your "skills" array. You don't reference this in your update, so what is your intention? Commented Jul 21, 2014 at 6:34
  • i am not dealing with count. problem is that i want call callback function when the loop is completed.The callback should return the result of executed query. Commented Jul 21, 2014 at 11:15

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

@SaurabhGhewari I'm intrigued. Suddenly this doesn't solve your problem how exactly? Does it not solve a problem you failed to specify correctly? Why remove the accept?
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.