Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

findOneAndUpdate overwriting attributes in 2+ level deep object passed as doc

Let's say I have this schema:

var UserSchema = new Schema({
    name : {
        firstName : String,
        lastName : String
    }
});

And I create this user:

User.create({
    name : {
        firstName : Bob,
        lastName : Marley
    }
}, function (err, user) {
    if(err) {
        return console.error(err);
    } else {
        return console.log(user);
    }
});

I noticed that if I do this:

User.findOneAndUpdate({_id: userId}, { name: { firstName : "Damian" } }, function (err, user) {
    if(err) {
        return console.error(err);
    } else {
        return console.log(user);
    }
});

My user now is:

user = {
    name : {
        firstName : "Damian"
    }
}

However, if I do this:

User.findOneAndUpdate({_id: userId}, { "name.firstName" : "Damian" }, function (err, user) {
    if(err) {
        return console.error(err);
    } else {
        return console.log(user);
    }
});

My user is:

user = {
    name : {
        firstName : "Damian",
        lastName : "Marley"
    }
}

Is there a way to pass an Object with not all of its attributes filled out to findOneAndUpdate, and keep the attributes that were there before, without getting rid of them? (same functionality as $set in Mongo). This is really annoying...

like image 650
bmpasini Avatar asked Feb 10 '23 03:02

bmpasini


1 Answers

Flatten your incomplete nested object with flat, like this:

var flatten = require('flat')

flatten({
    name : {
        firstName : "Damian"
    }
})

// { 
//   'name.firstName': 'Damian'
// } 

And now you can call findOneAndUpdate exactly as you did in your second example.

like image 96
Andrew Lavers Avatar answered May 19 '23 11:05

Andrew Lavers