cnak2
cnak2

Reputation: 1841

Updating sub sub documents not working

I have a app where I am trying to add contact records to a user "profile" document, where each record has arrays/subdocuments for multiple phone number and email addresses.

So the Profile Schema looks like this:

var ContactSchema = require('./contact');
var UserSchema = new Schema({

    first_name:{
      type: String
    },
    last_name:{
      type: String
    },
    contacts:[ContactSchema]
});

The ContactSchema looks like this:

var ContactSchema = new Schema({

    contact_name:{
      type: String
    },
    contact_age:{
      type: String
    },
    phones:[{
       phone_number:{type: String},
       phone_type:{type: String}
    }],
    emails:[{
       email_address:{type: String},
       email_type:{type: String}
    }]
});

I simplified the schemas above, but they essentially represent the structure of what I'm dealing with.

My challenge is in the ExpressJs/Mongoose API, where I want to pass the object and update the subdocuments.

Here is how I thought it would be done, but this does not work:

var express = require('express');
var router = express.Router();
var Profile = require('../models/profile');
var vCard = require('vcards-js');

router.route('/addcontact/:ownerId')

.put(function(req, res){

  Profile.findOne({'owner_id':req.params.ownerId}, function(err, profile){

    if(err)
      res.send(err);

    profile.contacts.push({
      first_name : req.body.first_name,
      last_name : req.body.last_name
    })

    req.body.phones.forEach(function(phone, index, arr){
      profile.contacts.phones.push({
        phone_type:phone.phone_type,
        phone_number:phone.phone_number
      })
    })

    req.body.emails.forEach(function(email, index, arr){
      profile.contacts.emails.push({
        email_type:email.email_type,
        email_address:email.email_address
      })
    })

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

  });
});


module.exports = router;  

So to clarify, I have an existing "User Profile" record. The user schema has a "contacts" array to hold multiple contacts. Each contact has phone and email arrays so each contact record can hold multiple emails and phone numbers.

What I'm trying to do is .PUT contact records and update the user Profile document.

Thanks for any sage advice!!

Upvotes: 0

Views: 46

Answers (2)

Sridhar
Sridhar

Reputation: 11816

Your User model doesn't seem to have owner_id. Assuming that it is missed out here and you wanted to add a new contact to the existing user.

'use strict';

var express = require('express');
var router = express.Router();
var Profile = require('../models/profile');

router.route('/addcontact/:ownerId').put(function (req, res) {
  var phones = req.body.phones;
  console.log('phones', phones);

  var emails = req.body.emails;
  console.log('emails', emails);

  var contacts = {
    contact_name: req.body.first_name,
    contact_age: '25',
    emails: emails,
    phones: phones
  };

  Profile.findOneAndUpdate({
    owner_id: req.params.ownerId
  }, {
    $push: {
      contacts: contacts
    }
  }, {
    new: true
  }, (err, profile) => {
    if (err) {
      return res.send(err);
    }
    return res.json(profile);
  });

});


module.exports = router;

And, one minor change I made to your code is adding return when sending response to avoid further execution of the code.

Upvotes: 1

Jackson
Jackson

Reputation: 914

var phonesArray = req.body.phones;
var emailsArray = req.body.emails;

Profile.findOneAndUpdate(
{'owner_id':req.params.ownerId}
{phones: {$push: {$each: phonesArray}}, emails: {$push: {$each: emailsArray }}}, function(err, profile){
    if(err)
      res.send(err);

    console.log(profile);
}

Upvotes: 0

Related Questions