0

I am working on node js app using express.js and mongodb with mongoose module to handle the database.

in one case I need to update a user property languages using findOneAndUpdate method. this property is an array of objects should looks like [{"language":"Ar","level":4}]

when I update it using the following nodejs code :

User.findOneAndUpdate({_id:mongoose.Types.ObjectId(req.body.id)}, 
 {$set:{[req.body.key]:req.body[req.body.key]}},(err,doc)=>{

  console.log(req.body) // {id:5d1619fa7c11fa102210ef86,"languages":[{"language":"Ar","level":4}],key:"languages"}
  if (!err) {
    res.json(200,doc);
  }else{
    res.json(500,{error:err});

  }
})

I get the following results

enter image description here

but when I try same thing from the mongo shell

db.users.findOneAndUpdate({"_id" : ObjectId("5d1619fa7c11fa102210ef86")},{ '$set': {"languages":[{"language":"Ar","level":4}]} })

I get the correct result

enter image description here

which is the correct expected results.

any idea why the nodejs snippet not working properly. thanks in advance.

Peter Wilson
  • 4,150
  • 3
  • 35
  • 62
  • make sure the schema is correct – Abhishek Anand Jun 29 '19 at 08:35
  • Thanks for your reply, the schema is correct. – Peter Wilson Jun 29 '19 at 08:37
  • i agree unless your body looks like `body = { key: "value", "value": "value2"}` your $set will always result as undefined with the syntax your using causing mongoose schema "protection" to kick in and voiding your chantes. – Tom Slabbaert Jun 29 '19 at 08:52
  • @tom I already logged the body in my code snippet above – Peter Wilson Jun 29 '19 at 09:00
  • mb didnt notice it, well the mongoosey syntax is correct and assuming the schema is too (unless you want to edit it in to double check this) the only other thing that can cause is problem is not sanitizng the body meaning level is equal to "4" and not 4. but again from the snippet this does not seem to be the case. with all these conditions met this code works as expected on my local. – Tom Slabbaert Jun 29 '19 at 09:09
  • @Neil Lunn , my question not related to the returned object. it's completely different than the question you marked it as duplicated of. – Peter Wilson Jun 29 '19 at 10:52

1 Answers1

0

I think you are not getting the updated result back after update has successfully run. you need to pass new : true in your update query as the third argument.

By default mongodb returns the old document after the update, but you can specify to return the updated document in the query.

Try this :

User.findOneAndUpdate({_id:mongoose.Types.ObjectId(req.body.id)}, 
 {$set:{[req.body.key]:req.body[req.body.key]},{new:true},(err,doc)=>{
  ...
  //doc will be updated doc here
})
Ravi Shankar Bharti
  • 8,922
  • 5
  • 28
  • 52