I am trying to add a product to a shopping cart in mongodb but the code I have written does not work. I have set up and if statement to check if the selected product's id is included in the items array and if true to console.log('match found'); within this if statement is also where my code that is not working is set up. Can you show me a better way to update the product quantity? I am writing the code for updating the item quantity exactly as it is in the docs shown here https://www.mongodb.com/docs/manual/reference/operator/update/inc/ so im at a loss.
const express = require('express');
const Carts = require('../repo/carts');
const router = express.Router();
router.post('/cart/products', (req, res) => {
Carts.findById(req.session.cartId, (err, foundCart) => {
if (err) {
console.log(err); // This err is for the find by Id, not to the update function
}
if (foundCart) {
console.log(foundCart);
console.log(req.body.productId);
let check = foundCart.items.map((item) => item.id.toString());
console.log(check);
if (check.includes(req.body.productId)) {
console.log('MATCH FOUND');
Carts.updateOne(
{ _id:foundCart._id}, { _id: req.body.productId,
$inc: { quantity: 1 } }
);
} else {
console.log('no match')
Carts.updateOne(
{ _id: foundCart._id },
{
$push: {
items: {
_id: req.body.productId,
quantity: 1,
},
},
},
(err, updatedCart) => {
if (err) {
console.log(err);
}
}
);
}
} else {
if (!foundCart) {
const newCart = new Carts({
_id: req.session.cartId,
items: [],
});
newCart.save();
}
}
});
res.send('product added to cart!!');
});
module.exports = router;
example of the array
items: [
{ quantity: 1, _id: '6356ffb3ece7e49784bfbd5d' },
{ quantity: 1, _id: '6356ffb3ece7e49784bfbd5d' },
{ quantity: 1, _id: '6356ff91ece7e49784bfbd5a' },
{ quantity: 1, _id: '6356ff75ece7e49784bfbd57' },
{ quantity: 1, _id: '63570003ece7e49784bfbd69' },
{ quantity: 1, _id: '63570003ece7e49784bfbd69' },
]
CodePudding user response:
I'm not really sure about this but it looks like you might have an issue with async methods.
This method does not have neither an await nor a callback function, so the proccess will continue (and maybe finish) without waiting for it to finish.
Carts.updateOne(
{_id: req.body.productId },
{ $inc: { quantity: 1 } }
);
https://mongoosejs.com/docs/api.html#query_Query-updateOne (If you look at the example there, it's being awaited)
On the other hand, you should get this block:
Carts.updateOne(
{ _id: foundCart._id },
{
$push: {
items: {
_id: req.body.productId,
quantity: 1,
},
},
},
(err, updatedCart) => {
if (err) {
console.log(err);
}
}
);
Inside of an else block. So if you find an existing item with the id you try to update it, but only if you don't find it you'll push a new item into the cart.
It should look something like this:
if (check.includes(req.body.productId)) {
console.log('MATCH FOUND');
Carts.updateOne(
{_id: req.body.productId },
{ $inc: { quantity: 1 } }
);
} else {
Carts.updateOne(
{ _id: foundCart._id },
{
$push: {
items: {
_id: req.body.productId,
quantity: 1,
},
},
},
(err, updatedCart) => {
if (err) {
console.log(err);
}
}
);
}
I hope that does the trick! :D
CodePudding user response:
Try with this logic:
router.post('/cart/products', async (req, res) => {
try {
let cart = await Carts.findById(req.session.cartId);
// Check if cart exists
if (!cart) {
// Create new cart
cart = await Carts.create({
_id: req.session.cartId,
items: [],
});
}
// Check if product is present
const productIndex = cart.items.findIndex(
(item) => item._id === req.body.productId
);
if (productIndex === -1) {
// Create new product
cart.items.push({
_id: req.body.productId,
quantity: 1,
});
} else {
// Update existing product
cart.items[productIndex].quantity = 1;
}
// Save updated cart
await cart.save();
res.status(200).send('product added to cart!!');
} catch (err) {
res.status(500).send('there was an error');
}
});