2

I have been trying to update the order status uisng nodejs and mongoose. But i came to problem on updating the status.

I have been trying to access the cart from ORDER document (table). I want to change the status inside cart from 'packed' to 'shifted'. I have been trying all day long but could not find the solution. Please help me with it. How can i select the cart and change the status in mongoose using nodejs?

ORDER

{
    "_id": {
        "$oid": "60a9a8b2bc65933bb4c22a3b"
    },
    "cart": [{
        "_id": {
            "$oid": "60a8bcafe7815c2950de4b28"
        },
        "userId": "60a3ad7fb51de12a5472de37",
        "count": "1",
        "status": "packed",
        "__v": 0
    }],
    "userId": "60a3ad7fb51de12a5472de37",
    "fName": "jay sree",
    "street": "5th cross hindurous",
    
}

MODEL

const mongoose = require('mongoose')

const schema = mongoose.Schema

const orderSchema = new schema(
  {
    userId: {
      type: String,
      required: true
    },
      cart: [{
          type: Object
      }],
      fName: {
      type: String,
      required: true
    },
    street: {
      type: String,
    },
  },
  {
    timestamps: true,
  }
);

module.exports = mongoose.model("Order", orderSchema)

Controller

exports.postUpdateStatus = (req, res, next) => {
    let status = req.params.status //shifted
    let productId =  mongoose.Types.ObjectId(req.params.productid )//60a8bcafe7815c2950de4b28
    let orderId = mongoose.Types.ObjectId(req.params.orderid )//60a9a8b2bc65933bb4c22a3b
    Order.find({id: orderId})
    .select({ cart: {$elemMatch: {id: productId}}})
    .then(product => {
        res.jsonp(product)
    })
    .catch(err => {
        console.log(err)
    })
}
xetryDcoder
  • 151
  • 1
  • 7

1 Answers1

2

You can call the findOneAndUpdate function and use the positional operator to update the matching cart-item. Something like:

Order.findOneAndUpdate({
    "_id": "60a9a8b2bc65933bb4c22a3b",
    "cart._id": "60a8bcafe7815c2950de4b28"
}, {
    "$set": {
        "cart.$.status": "shifted"
    }
}, {
    new: true
});

Note that I'm using the new-option here, in order for findOneAndUpdate to return the updated document.

Here's an example on mongoplayground where you can play around with the query: https://mongoplayground.net/p/5sW7NB1mJK7

eol
  • 23,236
  • 5
  • 46
  • 64
  • I tried but its not updating anything. Where could I have done wrong? do I need to upload more information? – xetryDcoder May 23 '21 at 12:01
  • Can you try converting your `id`s to mongoose `id`s explicitely? E.g. `let productId = mongoose.Types.ObjectId(req.params.productid);` Do this for both ids. – eol May 23 '21 at 12:28
  • yes ! tried that as well still no change. is there any alternative? – xetryDcoder May 23 '21 at 13:27
  • i did some changes ```Order.findOneAndUpdate({"cart._id": productId }, { $push: {"cart.status": status}}, {new: true})``` and made my code like this and now i am geting a error which says cannot create a field. any idea what is the issue? – xetryDcoder May 23 '21 at 14:26
  • You need to provide an index for `$push`, see https://stackoverflow.com/questions/27874469/mongodb-push-in-nested-array. But this won't solve your issue. Are you sure the id's are correct? Just for testing you could hard-code them instead of reading from the request. – eol May 23 '21 at 14:42
  • yes i saw it. what do you think i can do to make this work? – xetryDcoder May 23 '21 at 15:18
  • can you check my model? is there any problem with that? i have updated it – xetryDcoder May 24 '21 at 02:01
  • 1
    Thank you. It worked. Just i updaded the controller as you said and I had Problem with model. – xetryDcoder May 24 '21 at 02:56