Search code examples
mongoosemongoose-schema

Find id in an array of objects and update content via id


I have an array with multiple objects and I need to access one of the ids in the object so I can update the content in react. Currently, I am not seeing the state change when I make the update. The update worked fine when my data schema was just an object and had no arrays. Now that I changed my data structure I am no longer able to update my states. Below is the controller.

As an example, I want to access id 2 to update the notes state.

My question: what is the correct syntax to update the object by finding the id in that object?

  exports.updateCompany = async (req, res) => {
  let snapShotID = req.params.id;
  await findUpdateEmployee.findByIdAndUpdate(
    {
      _id: snapShotID,
      details: {
        $elemMatch: { id: req.params.detailsId) },
      },
    },
    {
      $set: { "details.$.notes": req.body.notes },
      new: true,
    },
    (err, data) => {
      if (err) {
        res.status(500).json({
          message: "update not created",
        });
      } else {
        res.status(200).json({
          success: true,
          message: "Post Updated",
          data,
        });
      }
    }
  );
};

Here is the model:

{
    "message": "Post found",
    "data": {
        "company": "Riteaid",
        "_id": "1",
        "details": [
            {
                "employee": "jane doe",
                "balance": "3",
                "notes": "some notes",
                "_id": "2"
            },
            {
                "employee": "john doe",
                "balance": "1",
                "notes": "some more notes",
                "_id": "3"
            }
        ],
    }
}

Solution

  • There are two things I needed to do, change the URL path from: someurl/:id to someurl/:companyId/employeeId

    The second was to edit the code from findByIdAndUpdate to findOneAndUpdate, and finally to follow the doc on how the code is structured with filter and update. Alos I used $elemMatch for the filter:

    exports.updateSnapShotTest = async (req, res) => {
      await CompanySnapShotTest.findOneAndUpdate(
        {
          _id: req.params.companyId,
          details: { $elemMatch: { _id: req.params.employeeId } } }, // FILTER
        {
          $set: {
            "details.$.notes": req.body.notes, // UPDATE
          },
        },
        { new: true, safe: true, upsert: true },
        (err, data) => {...});
          }
        }
      );
    };