Ömer Celep
Ömer Celep

Reputation: 5

Update on MongoDB from NodeJS doesnt work

I am able to run the following update command from command line:

db.Camera.update({_id:ObjectId("51059ca49c7b280809a2a81e")}, {$set: {"Selected":0}});

But the following code in NodeJS doesnt work. When I log item.Selected, I get a non-zero value.

exports.findById = function(req, res) {
    var ids = req.params.id.split(",");
    db.collection('Camera', function(err, collection) {
        for(var i = 0; i < ids.length; i++){
            collection.findOne({'_id':idArray[i]}, function(err, item) {
                item.Selected += 1;
                console.log('Selected: ' + item.Selected);
                collection.update({'_id':new BSON.ObjectID(ids[i])}, item,function(err, updated) {
                  if( err || !updated ) console.log("Not updated");
                  else console.log("Updated");
                });
            });
        }
    });

};

In the console, I always see "Not updated".

Thanks for your help.

Upvotes: 0

Views: 1220

Answers (2)

aciddaniel
aciddaniel

Reputation: 23

Problem I had was items ID, if you'll try to log the message you'll get an error saying something about uniqueness about ID blah bla :) so what I did was I saved id of existing item, then deleted it before the update gets called. Same thing was suggested by mongodb devs. so your code would look like:

id = item._id
delete item._id
collection.update(_id: id, item, function(err, updated){...}

Hope that'll help. And I also would recommend to use Mongoose.

Upvotes: 1

WiredPrairie
WiredPrairie

Reputation: 59763

The id inside the loop isn't what you expect because of your use of the variable i. These are callbacks, inside a closure. So, when the findOne returns, the loop has already finished, meaning it's really not what you expect as i will be equal to ids.length, for every "Camera."

You can just use the item's _id property directly when your code calls update (or anything else you'd like, just don't rely on the loop index, unless you wrap the code within the loop all with a closure which likely isn't necessary).

Something like this ... the query parameter to update call is what changed:

{'_id':item._id)}

Full code:

exports.findById = function(req, res) {
    var ids = req.params.id.split(",");
    db.collection('Camera', function(err, collection) {
        for(var i = 0; i < ids.length; i++){
            collection.findOne({'_id':ids[i]}, function(err, item) {
                item.Selected += 1;
                console.log('Selected: ' + item.Selected);
                collection.update({'_id':item._id)}, item,function(err, updated) {
                  if( err || !updated ) console.log("Not updated");
                  else console.log("Updated");
                });
            });
        }
    });

};

Upvotes: 1

Related Questions