cnak2
cnak2

Reputation: 1841

Trying to update nested / subdocument in Express

I have a Mongoose model that has nested array and a subdocument.

I seem to be ok when posting to the object arrays/subdocument, but I'm having trouble with the .put

I hard coded the params for testing, just in case they were not coming in from PostMan for some reason.

The result I get from the above code is an empty array!

So I'm getting the right record and it creates the "phone" array, but does not populate.

.put(function(req, res){
  Member.find({'_id':req.params.id}, function(err, member){
    if(err)
      res.send(err);

      member.phone.push({
        number: "78787878787",
        phoneType: 2
      })


    member.save(function(err){
      if(err)
        res.send(err);
      res.json(member);
    });
  });
});

I want to have an endpoint that simply adds another "phone" record.

Here is my model:

//DEPENDENCIES
var mongoose = require('mongoose');


var contactSchema = new mongoose.Schema({
  name:{type:String},
  age:{type:Number}
});

var phoneSchema = new mongoose.Schema({
  number:{ type: String },
  phoneType:{ type: Number }
})

var memberSchema = new mongoose.Schema({

  firstname: {
    type: String
  },
  lastname: {
    type: String
  },
  phone:[phoneSchema],
  contacts:[contactSchema]

  });

//RETURN MODEL

module.exports = mongoose.model('member', memberSchema);

Now when I run my code I get the following undefined for "members":

{ id: '587bcbffe64e9f28a6894dd7' }
[ { _id: 587bcbffe64e9f28a6894dd7,
    lastname: 'Stanley',
    firstname: 'Dave',
    __v: 0,
    contacts: [ [Object] ],
    phone: [] } ]
events.js:154
      throw er; // Unhandled 'error' event
      ^

TypeError: Cannot read property 'push' of undefined

Upvotes: 0

Views: 837

Answers (1)

Ravi Shankar Bharti
Ravi Shankar Bharti

Reputation: 9268

find returns an array of documents, not just one document. Thats is why it is giving error when you are trying to do member.phone.

Use findOne instead of find as you are querying by _id, it will return only one matched document or null(if its not present), so its a better choice than find.

Also, its better to check if the result is null or not. member will be null if no such _id is present.

Member.findOne({'_id':req.params.id}, function(err, member){
    if(err)
      res.send(err);
    else if(member!=null)
    {
        member.phone.push({
            number: "78787878787",
            phoneType: 2
        });
        member.save(function(err){...});
    }
});

If you are keen on using find. Use member[0] (first element) instead of member.

Member.find({'_id':req.params.id}, function(err, member){
    if(err)
      res.send(err);
    else if(member.length!=0)
    {
        member[0].phone.push({
            number: "78787878787",
            phoneType: 2
        });

        member[0].save(function(err){...});
    }
});

Hope that helps you.

Upvotes: 1

Related Questions