1

I am new in node and mongodb and I am trying to update the user password in the mongo database using node. I am getting the following error --

errmsg: 'After applying the update to the document {_id: ObjectId(\'5a4f50381a1152ec09277578\') , ...}, the (immutable) field \'_id\' was found to have been altered to _id: ObjectId(\'5a739493c592356f1b5a78b6\')' }

My code in models/accounts.js is

AccountSchema.static('passchange', function (password, callback) {
var that = this;
if (typeof userobj!="undefined") {
        console.log("User Object");
        console.log(userobj._id); //I am getting the user id here

        that.findOne({_id:userobj._id}, function (err, user) {
            if (!user) {
                console.log("No User");
                return callback(null, false);
            }
            else
            {
                var salt = this.salt = bcrypt.genSaltSync(10);
                var hash = bcrypt.hashSync(password, salt);

                var updatepwd = new that({
                    salt: salt,
                    hash: hash
                });
                var conditions = { _id: userobj._id }
                that.updateOne(conditions,updatepwd, function (err, savePassword) {
                    if (err)
                    {
                        console.log("err");
                        console.log(err);
                        return callback({err: err}, false);
                    } else {
                        console.log("savePassword._id");
                        console.log(savePassword._id);
                        //return callback(null, {_id : savePassword._id});
                    }
                });
            }
        });

    }
}); 

Any help is highly appreciated. Thanks in advance.

3
  • What is the value of "this?" And what is a "new" that? Those names aren't very descriptive. Commented Feb 1, 2018 at 22:45
  • 1
    Are you certain that updatepwd shouldn't be { '$set': { salt: salt, hash: hash } } instead? My understanding is that you're simply overwriting the entire document as opposed to updating specific values. The $set operator would fix this problem. Commented Feb 1, 2018 at 22:53
  • @B.Fleming Now working. Great. Thanks a lot for your help. Commented Feb 1, 2018 at 23:05

2 Answers 2

1

For the sake of documenting the solution:

As per the discussion in the comments, the problem appeared to be that the original document was being completely overwritten by the update, as opposed to only the hash and salt fields being updated. The appropriate fix was to update the updatepwd value to the following:

var updatepwd: { $set: {
    salt: salt,
    hash: hash
}};

The $set operator ensures that only salt and hash get updated, and thus the _id field (along with the rest of the data) remains untouched.

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

Comments

0

you may have to update the new operator because you are producing a new ID when you don't intend to change the ID, just the password. Try to follow the logic below instead of the new operator.

items.forEach(function (product) { //update or create new products

// Es6 assign
var productToUpdate = {};
productToUpdate = Object.assign(productToUpdate, product._doc);
delete productToUpdate._id;

Product.findOneAndUpdate({product_id: product.product_id}, productToUpdate, 
                     {upsert: true}, function (err) {
if (err)  return updateDBCallback(err);
   updateDBCallback(null, 'saved');
});
}); 

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.