8

The user has the option of updating any of a few values - however, if he only passes in { name: "new name" }, the email and password fields are also updated but to "null".

How can I only update the fields that are actually provided in req.body, leaving the rest as they are?

This is while still specifying which fields can be updated with a POST request - I've avoided just passing in req.body because I'd like to limit this.

My code looks like:

db.User.findOneAndUpdate({_id: req.params.id}, { 
        name: req.body.name,
        email: req.body.emaill, 
        password: req.body.password
})

Using something like name: req.body.name && req.body.name to check if a value is not undefined also overwrites with "null".

Thanks!

dan674
  • 1,848
  • 2
  • 15
  • 21

5 Answers5

13

Prepare your update object first:

let params = { 
        name: req.body.name,
        email: req.body.emaill, 
        password: req.body.password
};

for(let prop in params) if(!params[prop]) delete params[prop]; //This will not handle intentionally setting to false, empty string, null, 0, or other falsey values.

db.User.findOneAndUpdate({_id: req.params.id}, params);

Or, if your property names match:

let params = {};

for(let prop in req.body) if(req.body[prop]) params[prop] = req.body[prop];

db.User.findOneAndUpdate({_id: req.params.id}, params);
N-ate
  • 6,051
  • 2
  • 40
  • 48
  • Is that `.` right after `params` on the second line a typo? – Cyb3rL0rd Apr 26 '19 at 15:47
  • This line?: `db.User.findOneAndUpdate({_id: req.params.id}, params);` – N-ate Apr 30 '19 at 21:39
  • 1
    The `for(let prop in req.body) if ... params.[prop] = ... ` line. I was talking about the `.` between `params` and `[prop]` – Cyb3rL0rd May 01 '19 at 21:03
  • @N-ate what is this syntax called "for (let empty in params) if (!params[empty]) delete params[empty];" ?? – Grizzly Bear Sep 30 '20 at 08:16
  • It is usually referred to as for/in. https://www.w3schools.com/jsref/jsref_forin.asp#:~:text=The%20for%2Fin%20statement%20loops%20through%20the%20properties%20of,-%20loops%20through%20the%20properties%20of%20an%20object. – N-ate Sep 30 '20 at 16:15
1

const resu=await this.store.company.findByIdAndUpdate(companyId,
{ $set: { name,dba,description,foundedYear,contactInfo,clients,eVerified,socialMedia} , },
{new:true,omitUndefined:true},)

Use omitUndefined:true option

1

Use the option ignoreUndefined

const { name, email, password } = req.body;

db.User.findOneAndUpdate(
   { _id: req.params.id },    
   { $set: { 
       name,
       email,
       password
     }
   },        
   { ignoreUndefined: true }
)
Ryan Dantzler
  • 1,124
  • 1
  • 8
  • 18
0

If you plan to validate the data that is received you could create the update object with all fields that are valid. For example:

// Example post
const req = {
    body: {
        name: "First Last",
        email: "app@app.com",
        somethingElse: "I snuck in another update!"
    }
}

// Create update obj
const update = {}

// Destrcture the body to make if statments smaller to read
const {name,email,password} = req.body

// Test all values and add valide ones to update
if(name !== undefined && typeof name === 'string') {
    update.name = name
}

if(email !== undefined && typeof name === 'string') {
    update.email = email
}

if(password !== undefined && typeof password === 'string') {
    update.password = password
}

console.log(update)

Now use that update object inside your Mongo update. Of course you'd want to adjust the validations to check for things like email formatting or password requirements, plus probably cleaner to put them in a function but you get the idea.

-1

How about this?

db.User.findOneAndUpdate({_id: req.params.id}, req.body)

If your request looks exactly like in your sample ({ name: "new name" }) then this should have the desired effect.

dnickless
  • 10,733
  • 1
  • 19
  • 34
  • I wanted to limit what values could be updated by coding this onto the server instead of the client - otherwise maybe someone could send some post requests manually to update values that weren't meant to be updated. – dan674 Dec 18 '17 at 22:57