0

I have problem when I want update some field data from document embedded. I cannot update specific field without update whole document. If advanced have suggestion how to the best way to solve this. I really appreciate it.

This my request data:

{
    "userstatus": "tidak aktif",
    "password": "lukeskywalker"
}

This my user Schema (model):

'use strict';
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Attributes = new Schema({
  username:{type:String,unique:true,required:true,trim:true},
  email:{type:String,unique:true,required:true,trim:true},
  password:{type:String,required:true},
  hashpassword:{type:String},
  oldpassword:{type:String},
  salt:{type:String},
  usertype:{type:String,enum:['bisnis','personal']},
  userstatus:{type:String,enum:['aktif','tidak aktif','banned'],default:'tidak aktif'}
}, {_id:false});

const UsersSchema = new Schema({
  "type":{type:String, default:'users'},
  "attributes":Attributes
});
module.exports = mongoose.model('Users',UsersSchema);

This my code to edit user document:

//...update user
exports.editUsers = (req, res) => {
  let id = req.params.id;
  let body = req.body;
  let attrTemp = {attributes:{}};

  //...get key
  Object.keys(body).forEach((key) => {
    attrTemp.attributes[key] = body[key];
  });

  UsersModel.findOneAndUpdate(
  {"_id":id, "attributes.username":result.attributes.username},
  attrTemp.attributes,
  (err, result) => {
    if (err) {
      res.json(err);
    };

    res.json(result);
  });
};

This sample code is work when I do like this:

//...update user
    exports.editUsers = (req, res) => {
      let id = req.params.id;
      let body = req.body;
    
      UsersModel.findOneAndUpdate(
        {
          "_id":id, 
          "attributes.username":result.attributes.username
        },
        {
          //...hardcode to sample
          "attributes.userstatus":"tidak aktif",
          "attributes.password":"password"
        },
        (err, result) => {
          if (err) {
            res.json(err);
          };
    
          res.json(result);
        }
      );
    };

I want update only specific field who I send request to update. Not whole of my attributes. How the best way to do this.

Thanks advanced.

Sukma Saputra
  • 1,539
  • 17
  • 32
  • 1
    If your fields are embedded then you have to `$set` for each field like you have done in your second example... If you want to `$set` for the fields being passed then you have to take that fields in "ROOT" document – Ashh Aug 11 '18 at 05:39
  • Can you give me code for sample, because I don't get what you mean. thanks. – Sukma Saputra Aug 11 '18 at 06:13
  • 1
    I mean put your attributes fields in root document of the userSchema instead of embedded in `attributes`... something like that `const UsersSchema = new Schema({ type:{type:String, default:'users'}, username:{type:String,unique:true,required:true,trim:true}, email:{type:String,unique:true,required:true,trim:true}, password:{type:String,required:true}, hashpassword:{type:String}, oldpassword:{type:String}, salt:{type:String}, usertype:{type:String,enum:['bisnis','personal']}, userstatus:{type:String,enum:['aktif','tidak aktif','banned'],default:'tidak aktif'} });` – Ashh Aug 11 '18 at 06:21

1 Answers1

0

I have the answer from this Node.js - Mongoose - Update nested array with all values in req.body

And this my code:

//...update user
exports.editUsers = (req, res) => {
  let id = req.params.id;
  let body = req.body;
  let updateObj = {$set:{}};

  //...get key
  Object.keys(body).forEach((key) => {
    updateObj.$set['attributes.' + key] = body[key];
  });

  UsersModel.update({'_id':id}, updateObj, (err, result) => {
    if (err) {
      res.json(err);
    }
    res.json(result);
  });
};

Thanks.

Sukma Saputra
  • 1,539
  • 17
  • 32