0

I am attempting to increment the quantity of a line item in a cart object. Each Line Item has its own ObjectId as the same item can be added, but will have different attributes needed to process the order. Meaning that I need to look at the correct line, and not by the inventory item.

Database Record

Query ID's
{
  cartId: '6307c7ccb275c35cb6bb2b71',
  lineId: '6307c7d1b275c35cb6bb2b76'
}

Returned Results from Query No Update
{
  _id: new ObjectId("6307c7ccb275c35cb6bb2b71"),
  owner: '611afa8b9069c9126cff3357',
  discount: null,
  total: 101.94,
  items: [
    {
      itemId: '61cb88f25f499fd4563e99d9',
      sku: 1004,
      quantity: 1,
      price: 16.99,
      _id: new ObjectId("6307c7d1b275c35cb6bb2b73")
    },
    {
      itemId: '61cb88d85f499fd4563e99d3',
      sku: 1001,
      quantity: 1,
      price: 16.99,
      _id: new ObjectId("6307c7d1b275c35cb6bb2b76")
    },
    {
      itemId: '61cb89255f499fd4563e99e7',
      sku: 2003,
      quantity: 1,
      price: 16.99,
      _id: new ObjectId("6307c7d3b275c35cb6bb2b79")
    },
    {
      itemId: '61cb88df5f499fd4563e99d5',
      sku: 1002,
      quantity: 1,
      price: 16.99,
      _id: new ObjectId("6307c7d3b275c35cb6bb2b7c")
    },
    {
      itemId: '61cb89255f499fd4563e99e7',
      sku: 2003,
      quantity: 1,
      price: 16.99,
      _id: new ObjectId("6307c7deb275c35cb6bb2b7f")
    },
    {
      itemId: '61cb88d85f499fd4563e99d3',
      sku: 1001,
      quantity: 1,
      price: 16.99,
      _id: new ObjectId("6307cbcc3e81ef0f1a739cf9")
    }
  ],
  createdAt: 2022-08-25T19:04:44.859Z,
  updatedAt: 2022-08-25T19:26:51.714Z,
  __v: 0
}


exports.inc = async (req, res, next) => {
  console.log(req.body);
  const { cartId, lineId } = req.body;
  console.log(cartId);
  console.log(lineId);
  try {
    const updateCart = await Cart.findByIdAndUpdate(
      { _id: cartId, "item._id": lineId },
      { $inc: { quantity: 1 } },
      { new: true, returnDocument: "after" }
    ).exec();

    if (!updateCart) return next(new ErrorResponse("Unable to update the cart record", 404));

    console.log(updateCart);

    if (updateCart) {
      await calculateTotal(updateCart._id, updateCart.items, updateCart.discount);
      return sendRes(updateCart, 200, res);
    } else {
      return sendRes(updateCart, 201, res);
    }
  } catch (error) {
    console.log(error);
    next(error);
  }
};

The query is executing and processing the update based on the UpdateAt value, but the quantity isn't updating.

Please see let me know if you see anything off.

2 Answers2

0

try this

exports.inc = async (req, res, next) => {
  console.log(req.body);
  const { cartId, lineId } = req.body;
  console.log(cartId);
  console.log(lineId);
  try {
    const updateCart = await Cart.findByIdAndUpdate(
      { _id: cartId, "item._id": new mongoose.Types.ObjectId(lineId) },
      { $inc: { quantity: 1 } },
      { new: true, returnDocument: "after" }
    ).exec();

    if (!updateCart) return next(new ErrorResponse("Unable to update the cart record", 404));

    console.log(updateCart);

    if (updateCart) {
      await calculateTotal(updateCart._id, updateCart.items, updateCart.discount);
      return sendRes(updateCart, 200, res);
    } else {
      return sendRes(updateCart, 201, res);
    }
  } catch (error) {
    console.log(error);
    next(error);
  }
};

Nwekar Mahdi
  • 72
  • 1
  • 8
  • Seems to be the same outcome.. The update was processed without error, but nothing was updated. – Andrew Vargas Aug 25 '22 at 23:49
  • Take a look at this and it might help [link](https://stackoverflow.com/questions/15691224/mongoose-update-values-in-array-of-objects) – Nwekar Mahdi Aug 25 '22 at 23:59
  • I am attempting to query for the sub-array id shown below. `const updateCart = await Cart.findByIdAndUpdate( { "item._id": new mongoose.Types.ObjectId(lineId) }, { $inc: { "item.$.quantity": 1 } }, { new: true, returnDocument: "after", arrayFilters: [{ "item._id": lineId }] } ).exec();```` -> ERROR - Cast to ObjectId failed for value "{ 'item._id': new ObjectId("6307cbcc3e81ef0f1a739cf9") }" (type Object) at path "_id" for model "Cart". I also attempted to do it without the addition you mentioned. It fails to cast when a sting as well. – Andrew Vargas Aug 26 '22 at 00:14
  • wait in this line ``` { _id: cartId, "item._id": lineId } ``` it should be ``` "items._id" ``` – Nwekar Mahdi Aug 26 '22 at 00:26
  • I added upsert: true, and the query can't see items quantity. I understand why it's unable to because Items is an array of objects and quantity is inside of the object. What is the best way to access the object in the query? – Andrew Vargas Aug 26 '22 at 00:40
  • This is incrementing all the quantities in the array. How do I isolate it just to the lineId? const updateCart = await Cart.findByIdAndUpdate( { _id: cartId }, { $inc: { "items.$[].quantity": 1 } }, { new: true, returnDocument: "after", arrayFilters: [{ "items.$[]._id": lineId }] } ).exec(); – Andrew Vargas Aug 26 '22 at 00:47
0

Below is the correction to the Query.

    const updateCart = await Cart.findByIdAndUpdate(
      { _id: cartId, "items.&[element]._id": lineId },
      { $inc: { "items.$[element].quantity": 1 } },
      { new: true, returnDocument: "after", arrayFilters: [{ "element._id": lineId }] }
    ).exec();