简体   繁体   中英

nodejs / mongoose update a “multi level” value in document / cannot set property

I have a "User" collection, with some fields (name, firstname, login, password ...)

I want to store the user & password in a "sub document" named "local" (for the local connection, in the future I'll can have a subdocument named "facebook" or "google" ...)

So, here is the structure of a document in mongo :

db.User.find(){
    "__v": 0,
    "_id": ObjectId("5342b25940bcab2d1d71e04a"),
    "active": true,
    "address": "juddegaass, 2A",
    "api_key": "3cead67add74395ce4d1dfcdd3ea4979",
    "city": "Kehlen",
    "country": "LU",
    "create_date": ISODate("2014-04-07T14:12:41.104Z"),
    "credit": 0,
    "email": "admin@company.com",
    "firstname": "Admin",
    "lastname": "Istrator",
    "local": {
        "email": "admin@company.com",
        "password": "$2a$08$Y7GorE3UhceNhPzvAdv7X.wDNxp80snHdng0hq9r1AePqRW1iHU5i"
    },
    "role": "su",
    "uptade_date": ISODate("2014-04-07T14:12:41.104Z"),
    "zip": "8281"
}

I have a form to update the user, and my issue is when I submit this form. I got an error :

TypeError: Cannot set property 'email' of undefined

This is the update function in my Node User Mapper :

var toUpdate = {};

if (data.firstname) toUpdate.firstname = data.firstname;
if (data.lastname) toUpdate.lastname = data.lastname;
if (data.email) {
    toUpdate.email = data.email; 
    toUpdate.local.email = data.email;
}
if (data.password !== '') toUpdate.local.password = user.generateHash(data.password);
if (data.role) toUpdate.role = data.role;
...
if (data.apiKey) toUpdate.api_key = data.apiKey;
if (data.active) toUpdate.active = data.active;

dbUser.update({'_id' : data.id}, toUpdate, {upsert : true}, function (err) { 
    if (err) return callback(new Error(err));
    callback(null, data.id);
});

Sure, I can declare the "local" subobject but if I declare it, the password value will be removed.

Your comment makes it clear that you may already have an entry in the database for this item. As you're using mongoose, the correct way to update is to pull it out of the db first, then save it.

dbUser.findbyId(data.id, function(err, user){
  if(err){
    return callback(err);
  }
  if(!user){
    user = new dbUser();
  }
  if (data.firstname) user.firstname = data.firstname;
  //...//
  if(data.email){
     user.local = user.local || {}; 
     user.local.email = data.email;
  }
  if(data.password !== '') {
    user.local = user.local || {}; 
    user.local.password = dbUser.generateHash(data.password);
  }
  user.save(callback); 
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM