Home > Back-end >  Is there a way to update and push at the same time conditionally in Mongodb?
Is there a way to update and push at the same time conditionally in Mongodb?

Time:01-13

First of all, I apologize that the writing may not be natural because I used a translator.

I just started coding, and I don't know what's better or not. I will be grateful for your comments and help.

I'm currently implementing the cart function of the shopping mall.

If the status of the user's current cart is as follows:

let currentCart = [
  {
    id: "AAAAA",
    option: {
      delivery: "pickup",
      date: "2023.01.06",
      request: "request 1",
    },
    quantity: 1,
  },
  {
    id: "AAAAA",
    option: {
      delivery: "pickup",
      date: "2023.01.06",
      request: "request 2",
    },
    quantity: 1,
  },
];

When a user tries to add a new item to the cart as shown below:

let newCart = [
  {
    id: "AAAAA",
    option: {
      delivery: "pickup",
      date: "2023.01.06",
      request: "request 1",
    },
    quantity: 1,
  },
  {
    id: "BBBBB",
    option: {
      delivery: "pickup",
      date: "2023.01.06",
      request: "request 1",
    },
    quantity: 1,
  },
];

The results I want are as follows:

let result = [
  {
    id: "AAAAA",
    option: {
      delivery: "pickup",
      date: "2023.01.06",
      request: "request 1",
    },
    quantity: 2, // The cart that already exists adds quantity.
  },
  {
    id: "AAAAA",
    option: {
      delivery: "pickup",
      date: "2023.01.06",
      request: "request 2",
    },
    quantity: 1,
  },
  {
    id: "BBBBB",
    option: {
      delivery: "pickup",
      date: "2023.01.06",
      request: "request 1",
    },
    quantity: 1, // Cart that doesn't exist will be newly added.
  },
];

How can I implement these functions?

I tried the following code:

router.post("/addToCart", auth, async (req, res) => {
  const rootProductDoc = await Product.findOne({
    _id: req.body.productId,
  }).exec();

  User.findOne({ _id: req.user._id }, (err, result) => {
    let existingOptionStr = result.cart.map((cartItem) => {
      return JSON.stringify(cartItem.option);
    });

    let duplicateOption = req.body.option.filter((createdOption) => {
      return existingOptionStr.includes(JSON.stringify(createdOption));
    });

    if (duplicateOption) {
      for (let i = 0; i < duplicateOption.length; i  ) {
        User.updateMany(
          { _id: req.user._id, "cart.option": duplicateOption[i] },
          {
            $inc: { "cart.$.quantity": 1 },
          },
          {
            new: true,
          },
          (err, result) => {
            if (err) {
              return res.status(400).json({ success: false, err });
            } else {
              return res.status(200).send(result.cart);
            }
          }
        );
      }
    }
  });
});

According to the code above, updating the information that was previously contained in the cart works well.

But I'm currently stuck at implementing the remaining cases.

I want to run the same function as the code below at the same time.

User.updateMany(
  {
    _id: req.user._id,
  },
  {
    $push: {
      cart: {
        rootProductDoc: rootProductDoc,
        id: rootProductDoc.id,
        quantity: 1,
        option: req.body.option,
      },
    },
  },
  {
    new: true,
  },
  (err, result) => {
    if (err) {
      return res.status(400).json({ success: false, err });
    } else {
      return res.status(200).send(result.cart);
    }
  }
);

What should I do to get the expected result as above?

CodePudding user response:

First of all, Check the cart, Item is exists or not. if exists, then update the quantity of the item, If item is not exists then add new item in the cart.

For example:

router.post("/addToCart", auth, async(req, res) => {
  const rootProductDoc = await Product.findOne({
    _id: req.body.productId
  }).exec()

  User.findOne({
    _id: req.user._id
  }, (err, result) => {
    let existingItem = result.cart.find((item) => {
      return item.id === rootProductDoc.id && item.option === req.body.option
    })

    if (existingItem) {
      //  item exists in cart, so update the quantity of the item
      User.updateMany({
          _id: req.user._id,
          "cart._id": existingItem._id
        }, {
          $inc: {
            "cart.$.quantity": 1
          }
        }, {
          new: true
        },
        (err, result) => {
          if (err) {
            return res.status(400).json({
              success: false,
              err
            })
          } else {
            return res.status(200).send(result.cart)
          }
        }
      )
    } else {
      // item does not exist, so add to the cart
      User.updateMany({
          _id: req.user._id
        }, {
          $push: {
            cart: {
              rootProductDoc: rootProductDoc,
              id: rootProductDoc.id,
              quantity: 1,
              option: req.body.option
            }
          }
        }, {
          new: true
        },
        (err, result) => {
          if (err) {
            return res.status(400).json({
              success: false,
              err
            })
          } else {
            return res.status(200).send(result.cart)
          }
        }
      )
    }
  })
})

If you face any problem. Please let me know

  • Related