I'm trying to decrement a value using key in mongoose collection.
So, what exactly I want is that totalPrice value should be decreased by that product price value along with quantity by -1.
Here is my Cart schema:
var mongoose = require('mongoose');
let itemSchema = mongoose.Schema({
product: {
type: mongoose.Schema.Types.ObjectId,
ref: "Product"
},
quantity: Number,
price: Number
});
var cartSchema = mongoose.Schema({
userID: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
items: [itemSchema],
totalPrice: { type: Number, default: 0 },
});
module.exports = mongoose.model('Cart', cartSchema);
Here is my controller:
module.exports.deleteCartItem = async (req, res, next) => {
const { productID } = req.params;
const cart = await Cart.findOneAndUpdate({
userID: req.user._id,
"items.product": productID
}, {
$inc: {
'items.$.quantity': -1,
totalPrice: -price
}
}, { new: true });
}
My cart collection:
{
"_id": {
"$oid": "61d49c20e59e3f2690966ffb"
},
"totalPrice": 1098,
"userID": {
"$oid": "6187fe7cacbffaf7d01a3e23"
},
"items": [{
"_id": {
"$oid": "61d49c20e59e3f2690966ffc"
},
"product": {
"$oid": "61d1bb34cfa792063ca5d86d"
},
"quantity": 2,
"price": 499
}, {
"_id": {
"$oid": "61d56763340e1607788c8831"
},
"product": {
"$oid": "61d1bc25cfa792063ca5d86e"
},
"quantity": 1,
"price": 100
}]
}
Final result which I want when deleteCartItem is called:
{
"_id": {
"$oid": "61d49c20e59e3f2690966ffb"
},
"totalPrice": 599,
"userID": {
"$oid": "6187fe7cacbffaf7d01a3e23"
},
"items": [{
"_id": {
"$oid": "61d49c20e59e3f2690966ffc"
},
"product": {
"$oid": "61d1bb34cfa792063ca5d86d"
},
"quantity": 1,
"price": 499
}, {
"_id": {
"$oid": "61d56763340e1607788c8831"
},
"product": {
"$oid": "61d1bc25cfa792063ca5d86e"
},
"quantity": 1,
"price": 100
}]
}
Error:
ReferenceError: price is not defined at module.exports.deleteCartItem (E:\Projects\mean\server\controllers\cartController.js:143:59)
and if I removed the totalPrice line the quantity is decreasing successfully.
Is there a way to achieve that?? Please help. Thanks
CodePudding user response:
Indeed, price is not defined and thus, when you try to update your total price with totalPrice: -price, it raises an error.
Assuming you want to update this key with the price contained in your document, you'll have to first retrieve your document and only then update it:
module.exports.deleteCartItem = async (req, res, next) => {
const { productID } = req.params;
const originalCart = await Cart.findOne({
userID: req.user._id,
"items.product": productID
});
const priceToReduce = originalCart.items.find(item => item['$oid'] === productID);
await originalCart.updateOne( {
$inc: {
'items.$.quantity': -1,
totalPrice: -priceToReduce
}
});
}
Please note that updateOne will not return the modified object (as it would with findOneAndUpdate with the new: true option). If you really need to get the modify object, just do the same code and replace the updateOne func with findOneAndUpdate (a bit redundant since we already had to retrieve the original object for our purpose):
module.exports.deleteCartItem = async (req, res, next) => {
const { productID } = req.params;
const originalCart = await Cart.findOne({
userID: req.user._id,
"items.product": productID
});
const priceToReduce = originalCart.items.find(item => item['$oid'] === productID);
const newCart = await Cart.findOneAndUpdate({
userID: req.user._id,
"items.product": productID
},
{
$inc: {
'items.$.quantity': -1,
totalPrice: -priceToReduce
}
},
{
new: true
});
}
Also, this does not handle any sort of error that could potentially happen (what if find(item => item.oid === productID); doesn't find anything? what if productID is undefined/null?).
