Gaurav_soni
Gaurav_soni

Reputation: 6114

Nodejs findOneAndUpdate paramerters

I have a user model with the following schema, all fields required

name:String, 
country:String,
age:Number

From frontend i press update button and update only the age field, and on backend i have the following

var body = _.pick(req.body, ["candidateId","name","age","country"]);
var candidateId = mongoose.Types.ObjectId(body.candidateId);

Candidate.findOneAndUpdate({
        _id:candidateId
    },{
        name: body.name,
        country: body.country,
        age: body.age,
    }).then((data) => {
        if (!data) {
            res.status(400).send('noDataFound');
        } else {
            res.status(200).send(data);
        }
    }).catch((e) => {
        res.status(500).send(e)
    })

Front passes the data as follows

{   "candidateId":"5a9a86c16acff45a8070d2da",
     "name":"Superman",
}

I will get get undefined error for body.age and body.country since its not passed from front end.

QUESTION - How can use the previous values if no value is send from front end for some parameter, one approach is to send everything even if its not changed.

Upvotes: 0

Views: 111

Answers (4)

Andy Gaskell
Andy Gaskell

Reputation: 31761

It looks like you're using lodash, check out omitBy to remove undefined or null properties:

_.omitBy({ foo: 'foo', bar: undefined, baz: null }, _.isNil)
{foo: "foo"}

Here's a vanilla JS solution:

Object
  .entries({ foo: 'foo', bar: undefined, baz: null })
  .filter(([_, value]) => value !== null && value !== undefined)
  .reduce((acc, [key, value]) => { acc[key] = value; return acc; }, {})

Upvotes: 1

Gaurav_soni
Gaurav_soni

Reputation: 6114

I am using the following way to go around it , if any other better approach is there let me know ill mark that as answer.

I am now passing all the data to update from frontend in a new object like this

--- Client Data---

{   "candidateId":"5a9a86c16acff45a8070d2da",
    "updatedData":{
        "firstName":"Jack",
        "lastName":"Bauer",
        "applicationSource":"consultant",
        "skills":["trading","sales"]    
    }
}

---- Updating logic ----

var body = _.pick(req.body, ["candidateId","updatedData"]);
    var candidateId = mongoose.Types.ObjectId(body.candidateId);

    var dataToUpdate = _.pick(body.updatedData,["firstName","lastName"]);

    Candidate.findOneAndUpdate({
        _id:candidateId
    },dataToUpdate).then((data) => {
        if (!data) {
            res.status(400).send('noDataFound');
        } else {
            res.status(200).send(data);
        }
    }).catch((e) => {
        res.status(500).send(e)
    })

Upvotes: 0

tyb
tyb

Reputation: 201

Form a new object that includes sent values:

const newObj = {};

if (body.name) {
  newObj.name = body.name;
}

if (body.age) {
  newObj.age = body.age;
}

if (body.country) {
  newObj.country = body.country;
}

Then update using newObj.

Candidate.findOneAndUpdate({
        _id:candidateId
    }, newObj)...

Upvotes: 0

guijob
guijob

Reputation: 4488

When I'm facing this problem I usually create a parser function as:

var body = _.pick(req.body, ["candidateId","name","age","country"]);
var candidateId = mongoose.Types.ObjectId(body.candidateId);

function createUpdatedValues(params) {
  var condition = {};
  if (params.candidateId) condition.candidateId = params.candidateId;
  if (params.name) condition.name = params.name;
  if (params.age) condition.age = params.age;
  if (params.country) condition.country = params.country;
  return condition;
}    

Candidate.findOneAndUpdate({
        _id:candidateId
    },createUpdatedValues(body)).then((data) => {
        if (!data) {
            res.status(400).send('noDataFound');
        } else {
            res.status(200).send(data);
        }
    }).catch((e) => {
        res.status(500).send(e)
    })

Upvotes: 0

Related Questions