11

I would update a collection setting the value only if the new values are not null. I have a code like this:

 ...
 var userName = req.body.nome;
 var userSurname = req.body.cognome;
 var userAddress = req.body.indirizzo;

 collection.update(
     {_id:ObjectId(req.session.userID)},
     {$set: { nome: userName, cognome: userSurname, indirizzo: userAddress }}
 )

Is there an easy way for doing this?

ANOTHER WAY: if I could take the value req.body.* from the placeholder of the form where I take the data, I could solve the problem.. but is this possible?

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
Nicola
  • 465
  • 2
  • 7
  • 19

10 Answers10

26

You could try something like this:

var objForUpdate = {};

if (req.body.nome) objForUpdate.nome = req.body.nome;
if (req.body.cognome) objForUpdate.cognome = req.body.cognome;
if (req.body.indirizzo) objForUpdate.indirizzo = req.body.indirizzo;

//before edit- There is no need for creating a new variable
//var setObj = { $set: objForUpdate }

objForUpdate = { $set: objForUpdate }

collection.update({_id:ObjectId(req.session.userID)}, objForUpdate )
3UMF
  • 5,162
  • 2
  • 15
  • 26
Ivan.Srb
  • 1,851
  • 1
  • 14
  • 10
  • 6
    If you have a lot of parameters/fields, it might not look so nice and you'll end up on r/programminghorror – Fusseldieb May 30 '19 at 11:35
5

You can use lodash like this other question: https://stackoverflow.com/a/33432857/4777292

_.pickBy({ a: null, b: 1, c: undefined }, _.identity);

would be

{b:1}

Edward Newsome
  • 723
  • 7
  • 15
2

Are you not just asking to pass in all the fields that you posted? Why not do this then?

(And basically just a cut and paste of your code):

collection.update(
    {_id: ObjectId(req.session.userID)},
    {$set: req.body }
)

Then whatever content you posted as fields is set within your update.

Note that use of set will only overwrite, or add new fields. If you just want to replace the whole document, then remove the whole {$set: (..) } notation and just pass in req body as it's a valild object.

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
  • 1
    No, it was a data user form editing so the field that aren't modifield haven't to be modified.. in this way I replace them with nothing – Nicola Feb 27 '14 at 15:53
1

You can use mongoose for that by casting req.body to your model,

I assume you have mongoose model called User, and in your controller,

var userModel = new User(req.body);
User.update({_id: req.session.userID}, userModel, {upsert: true}, function(err){
   console.log("Error occured!");
});

There is no mongoose tag, but I strongly recomment to use that. For more details;

Mongoose Update

Mongoose Model

Hüseyin BABAL
  • 15,400
  • 4
  • 51
  • 73
  • You don't need to manually cast to `ObjectId` when using Mongoose; the casting based on the schema is one of the key benefits. – JohnnyHK Feb 27 '14 at 15:13
0

If there is not any field that you dont want users to be able to change. since this method will take any value which is not empty and update it. you can do it like this.

 const updatedFields = {};
 Object.keys(req.body).forEach(key => {
   if (!isEmpty(req.body[key])) {
     updatedFields[key] = req.body[key];
   }
 });
YourModel.findOneAndUpdate(
      { employee_id: req.body.employee_id },
      {$set:updatedFields},
      {new:true}).then(updatedObj =>{
        console.log("updated obj:",updatedObj);
      })

is empty function

    const isEmpty = value =>
  value === undefined ||
  value === null ||
  (typeof value === "object" && Object.keys(value).length === 0) ||
  (typeof value === "string" && value.trim().length === 0);
Yash Ojha
  • 792
  • 9
  • 17
0

This version still allows for null string fields to be respected and updated. Omitted fields would be ignored.

const cleanedObject = Object.keys(origObject).reduce((acc, k) => {
  if (typeof origObject[k] === "undefined") return acc;
  acc[k] = origObject[k];
  return acc;
}, {});

collection.update({_id:ObjectId(req.session.userID)}, cleanedObject })
Adrian Bartholomew
  • 2,506
  • 6
  • 29
  • 37
0

Probably you've got already user authenticated so you should have req.user.*

in this case you can use ternary operator to assign the value and update it with either new one or the current one (so there is no update)

var userName = req.body.nome ? req.body.nome : req.user.nome;
var userSurname = req.body.cognome ? req.body.nome : req.user.cognome;
var userAddress = req.body.indirizzo ? req.body.indirizzo : req.user.indirizzo;

collection.update(
     {_id:ObjectID(req.session.userID)},
     {$set: { nome: userName, cognome: userSurname, indirizzo: userAddress }}
)

If you don't have req.user then you can do it in 3 steps. 1. find user in collection 2. get current data 3. update data with new or current (as above)

let currentName
let currentSurname
db. collection.findOne({_id: ObjectID(req.session.userID)}, (err, user) => {
    if (err) { } // handle error here
    else if (user) {
        currentName = user.name
        currentSurname = user.surname
    }
})
Matt
  • 51
  • 1
  • 7
0
let objForUpdate = {}
for (const key of Object.keys(req.body)) {
  if (req.body[key]) objForUpdate = Object.assign({}, objForUpdate, { [key]: req.body[key] })
} 

collection.update({_id:ObjectId(req.session.userID)}, { $set:  objForUpdate })

This will dynamically add fields in objForUpdate if defined in the body.

Tyler2P
  • 2,324
  • 26
  • 22
  • 31
PhillipeG
  • 1
  • 1
0
var userName = req.body.nome;
var userSurname = req.body.cognome;
var userAddress = req.body.indirizzo;

collection.update(
  { _id: ObjectId(req.session.userID) },
  {
    $set: {
      ...userName && { nome: userName },
      ...userSurname && { cognome: userSurname },
      ...userAddress && { indirizzo: userAddress },
    },
  }
)
Poyoman
  • 1,652
  • 1
  • 20
  • 28
-1

The answer by Hüseyin BABAL is on the right track, but that will generate a warning from mongo because calling new User() will create a new _id which is immutable. What you want to do is the following:

const userModel = Object.assign(req.body);
User.update({_id: req.session.userID}, userModel, {upsert: true}, 
  function(err){
    console.log("Error occured!");
  });
anderskev
  • 124
  • 2
  • 5