2

I would like the nested object with the id 5f0e14241f5ccb42d8742767 to be updated:

 {
        "_id": "5f0b33ab52a4e966c754d963",
        "make": "Toyota",
        "model": "Prius",
        "engine": "1.8",
        "insurances": [
            {
                "yearlyPremium": {
                    "$numberDecimal": "60.39"
                },
                "_id": "5f0e14241f5ccb42d8742767",
                "startDate": "1970-01-19T09:31:15.550Z",
                "monthlyPremium": {
                    "$numberDecimal": "5.49"
                },
                "excess": 100
            },
            {
                "yearlyPremium": {
                    "$numberDecimal": "71.39"
                },
                "_id": "5f0e147c0340243eb03b5247",
                "startDate": "1970-01-19T09:31:15.550Z",
                "monthlyPremium": {
                    "$numberDecimal": "6.49"
                },
                "excess": 100
            },
       ]
 }

So in my PATCH rest api request, I just want to change the monthly premium, from what it is currently 5.49 to 1.50. Hence I pass the carId: 5f0b33ab52a4e966c754d963 and the particular inusranceId: 5f0e14241f5ccb42d8742767 (nested in Car object) as query params, to identify which insurance in the insurances array needs updating. Then in the request body I pass the item to be modified (monthlyPremium):

enter image description here

I followed the stack overflow solution: mongoDB: Update nested array object

So this is what I tried:

router.route('/insurance')
.patch(async (req, res) => {
    const { carId, insuranceId } = req.query
    const { startDate, monthlyPremium, excess } = req.body
    try {
        const foundCar = await Car.findById(carId)
        const foundCar = foundCar.insurances.filter(ins => {
            return ins._id == insuranceId
        })
        
        foundInsurance.startDate = startDate && new Date(startDate * 1000) || foundInsurance.startDate,
        foundInsurance.monthlyPremium = monthlyPremium && parseFloat(monthlyPremium) || foundInsurance.monthlyPremium,
        foundInsurance.yearlyPremium = monthlyPremium && parseFloat(monthlyPremium) * 12 || foundInsurance.yearlyPremium,
        foundInsurance.excess = excess && Number(excess) || foundInsurance.excess
        
        Car.update(
            {_id: carId, "insurances._id": insuranceId}, 
            {$set: {"insurances.$":foundInsurance}}
        )

        res.send(`Insurance updated`)
    } catch (err) {
        res.status(400).json({ error: err })
    }
})

The request queries are captured correctly in the code. The request succeeds and returns Insurance updated, but nothing gets updated. Everything is working except the update method is not updating the info monthlyPremium to 1.50.

UPDATE

@Mahan, I tried your suggested approach, unfortunately the record still hasn't changed. Printing foundInsurance I get this (it doesn't print the values in the console, just the meta data):

found insurance: {
  yearlyPremium: Decimal128 {
    _bsontype: 'Decimal128',
    bytes: <Buffer 97 17 00 00 00 00 00 00 00 00 00 00 00 00 3c 30>
  },
  _id: 5f0e14241f5ccb42d8742767,
  startDate: 1970-01-19T09:31:15.550Z,
  monthlyPremium: Decimal128 {
    _bsontype: 'Decimal128',
    bytes: <Buffer 25 02 00 00 00 00 00 00 00 00 00 00 00 00 3c 30>
  },
  excess: 100
}

1 Answer 1

1

Please try using mongoose arrayFilters like this:

Car.update(
  { _id: carId }, 
  { $set: { "insurances.$[elem]": foundInsurance } },
  { arrayFilters: [ { 'elem._id': insuranceId } ] }
)

Sign up to request clarification or add additional context in comments.

14 Comments

Thanks Mahan. Actually now I'm getting an error on POSTMAN for that endpoint. { "error": { "stringValue": "\"insurance\"", "kind": "ObjectId", "value": "insurance", "path": "_id", "reason": {} } } Not sure why. It's the same setup you see in the screenshot in my question for POSTMAN
Would you please post your foundInsurance object ? After you set its properties.
Ok the problem right now is with the PATCH endpoint. Even if I empty the whole body of the call back (for the API) from any code, I'm still getting this error. So there must be an issue with the endpoint. I can't see where the issue is!!!
Do you set app.use(bodyParser.json()); middleware in your express app.js ?
And also app.use(bodyParser.urlencoded({extended: false}));
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.