skip to Main Content

Alright, this might have been asked quite a lot of times but none of them gives me a solution.

Here’s my schema.

{ 
    "_id" : ObjectId("23453453453453"), 
    "title": "Item 01"
    "checkList" : [ 
            { 
                "ch_id" : "621eff4e0ed5c751adaa42fb", 
                "status" : "statu", 
                "dateMonthYear" : 1646286480139.0, 
                "val" : "Gopi", 
                "remarks" : "Good", 
                "_id" : ObjectId("7555777575") 
            }, 
            { 
                "ch_id" : "621eff4e0ed5c751adaa42fb", 
                "status" : "status", 
                "dateMonthYear" : 1646286480139.0, 
                "val" : "Gopi", 
                "remarks" : "Good", 
                "_id" : ObjectId("7555777575") 
            } 
    ]
}

What I want to do is update the status in the 2nd object in the checklist array. I can use the following query to update this just fine.

const itemUpdated =  await Item.updateOne(
    {_id: id, 'checklist._id': req.params.id},
    {$set: { "checklist.$.status": req.body.status }},
);

But, I want to use Mongoose method like save() to update this. Not RAW query. Because with Mongoose methods, I get extra layer of validation and middleware. I checked all over internet but only found ones with raw queries.

How to update a nested object in array with Mongoose ORM ?

2

Answers


  1. Chosen as BEST ANSWER

    I finally found this solution that works best for this situation. I don't know why Mongoose docs are so poorly written.

    If we have an array of subdocuments, we can fetch the one we need with id() method provided by Mongoose.

    const item = await Item.findById(id);
    checkListItem = item?.checklist.id(req.params.id);
    
    if(checkListItem){
      checkListItem.status = req.body.status;
      item?.save();
    }
    

    This worked for me. Hope someone might find this useful!


  2. Retrieve the Item and loop to its checkList updating the status:

    const item = await Item.findOne({ _id: id, 'checklist._id': req.params.id });
    if (!item || item.checkList.length === 0) return;
    for (let i = 0; i < item.checkList.length; i++) {
        item.checkList[i].status = req.body.status;
    }
    await item.save();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search