Meteor and MongoDB: Dynamically updating properties of objects nested within an array

Before we get into some of the code we will make the following assumptions:

  1. Our document set is named Schedule
  2. We are using ES2015+

Take this example document structure:

{
  _id: '123-456-789',
  ownerId: '123',
  schedule: [
    {
      _id: '432-1234-12',
      sectionTitle: 'Section 1',
    },
    {
      _id: '222-111-232',
      sectionTitle: 'Section 2',
    }
  ],
}

The following will update sectionTitle to String: Module 1.

Schedule.update({
  _id: '123-456-789',
  'schedule._id': '432-1234-12',
}, 
{
  $set: {
    'schedule.$.sectionTitle': 'Module 1'
  }
});

Going further by defining a Meteor method to handle this dynamically.

Now let's say we wanted to update only the sectionTitle property where our current working section id is unknown.

Here is a meteor method that would handle just that thing:

Meteor.methods({
  'Schedule.update-section-title'( 
    scheduleId,
    sectionId,
    sectionTitle ) {
    
    Schedule.update( { 
      _id: scheduleId, 
     'schedule._id': sectionId
    },
    {
      $set: {
        'schedule.$.sectionTitle': sectionTitle
      }
    } );
  }

});

Describing the code

For the point of this exercise, let's hone in really on the Schedule.update... portion of this code.

MongoDB says that we can target an object within a nested collection by using nesting syntax. For example the 'schedule._id': sectionId portion of the query will provide a handle to our update target as the $ alias. So later in our update instruction, we are afforded schedule.$ access to any property on the found object.

Example usage

And to invoke this we would use the Meteor.call() API:


Meteor.call(
  'Schedule.update-section-title', 
  '123-456-789', // our section document ID
  '432-1234-12', // our target section _id
  'New title!' // the new title we wish to update the section with
);