Express JS How to push object to an array of child object

Viewed 185

I'm working on a school directory and I want to push objects to my locations array, which is a property of my child object Floor that belongs to a Parent Object called Map.

Floor Schema

const floorSchema = new mongoose.Schema({
    title:{
      type:String,
      required:true
    },
    file:{
      type:String,
      required:true
    },
    floorSlug:{
      type:String,
      required:true,
    },
    locations:[{
        locationTitle: String,
        locationSlug: String,
        description: String,
        position_x: String,
        position_y: String,
        position_z: String,
    }],
})

My route to add location objects stands like this which I tried to "edit the floor", specifically trying to push to the locations property:

router.patch('/:slug/:floorSlug/add-location', (req, res) => {
  const slug = req.params.slug;
  const { floorSlug } = req.body;
  const querySlug = '^' + slug + '$';
  const locations = req.body.locations;
  Map.findOneAndUpdate(
      {
        $and: [
          { "slug": { '$regex': querySlug, $options: 'i' } },
          { 'floorSlug': floorSlug }]
      },
      {
        $push: { "locations": locations }
      }
  )
  .then(map => {
    map.floors.push({
      locations
    })
    map.save()
      .then(map => res.json(map))
      .catch(err => res.status(400).json('Error: ' + err));
  })
  .catch(err => res.status(400).json('Error: ' + err))

});

My expected result should look like this:

    {
    "map": [
        {
            "floors": [
                {
                    "title": "upper level",
                    "file": "mapurl.com",
                    "floorSlug": "upper-level"
                    "locations": [
                        {
                            "locationTitle": "title",
                            "locationSlug": "title-1",
                            "description": "description",
                            "position_x": "1",
                            "position_y": "1",
                            "position_z": "1"
                        }
                    ]
                },
                {
                    "title": "lower level",
                    "file": "mapurl.com",
                    "floorSlug": "lower-level",
                    "locations": [
                        {
                            "locationTitle": "title",
                            "locationSlug": "title-1",
                            "description": "description",
                            "position_x": "1",
                            "position_y": "1",
                            "position_z": "1"
                        }
                        {
                            "locationTitle": "title",
                            "locationSlug": "title-2",
                            "description": "description",
                            "position_x": "2",
                            "position_y": "2",
                            "position_z": "2"
                        }
                    ]
                }
            ],
            "_id": "61cfb0911dfb0970a0eb00cb",
            "title": "map",
            "slug": "map-1",
        }
    ]
}

Thanks for your help!

1 Answers

You can do it using $push.

I think this code may help you !

router.patch('/:slug/:floorSlug/add-location', (req, res) => {
  const slug = req.params.slug;
  const { floorSlug } = req.body;
  const querySlug = '^' + slug + '$';
  const locations = req.body.locations;
  Map.findOneAndUpdate(
    {
      $and: [
        { "slug": { '$regex': querySlug, $options: 'i' } },
        { 'floors.floorSlug': floorSlug }]
    },
    {
      $push: { 'floors.$.locations': locations }
    }
  );
});
Related