let cart = req.body.params.cart // array of objects that needs to be updated if exists in db, if not upsert it.
let userid = req.body.params.uid
for (let i = 0; i < cart.length; i++) {
Cart.updateOne({ user: userid, 'cart.product': cart[i].product._id },
{
$set: {
'cart.$.quantity': cart[i].quantity
}
},
{ upsert: true }// works without this line of code, updates the objects if exists
)
}
my cart model:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const CartSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'users'
},
cart: [{
product: {
type: Schema.Types.ObjectId,
ref: 'productlist'
},
quantity: {
type: Number
},
date: {
type: Date,
default: Date.now
}
}]
})
module.exports = Cart = mongoose.model('cart', CartSchema)
I'm trying to update a users shopping cart with new items that are in the cart array. I need to check if product exists, if yes update quantity, if not push it in to user's cart. Somehow it doesnt work with $upsert. without $upsert document gets updated if object id exists in the user's cart.
Working version with tons of clutter. I feel like there is a better way of doing it like the one I was trying to do above. I would appriceate any help, reducing clutter here.
Cart.find({ user: req.body.params.uid })
.then(userCart => {
if (userCart[0].cart.length === 0) {
for (let i = 0; i < cart.length; i++) {
Cart.updateOne({ user: req.body.params.uid }, {
$push: {
cart: {
product: cart[i].product._id,
quantity: cart[i].quantity
}
}
}).catch(err => console.log(err))
}
}
else {
cart.reduce((acc, element) => {
let index = userCart[0].cart.findIndex(val => val.product._id == element.product._id)
if (index !== -1) {
Cart.findOneAndUpdate({ user: req.body.params.uid, 'cart.product': element.product._id },
{
$set: {
'cart.$.quantity': element.quantity
}
},
{ new: true }
).then(a => console.log(a))
}
else {
Cart.updateOne({ user: req.body.params.uid }, {
$push: {
cart: {
product: element.product._id,
quantity: element.quantity
}
}
}).catch(err => console.log(err))
}
acc.push(element)
return acc
}, [])
}
})
Sample value from array cart
product: {
_id: '5eaf8eeac436dbc9b7d75f35',
name: 'Strawberry',
category: 'organic',
image: '/productImages/australian.jpg',
price: '9.65'
},
quantity: 6
sample cart in db :
_id: 5ec12ea36ccf646ff5aeef0c,
user: 5ec11a8f69ccf46e0e19c5ef,
cart: [
{
date: 2020-05-18T10:26:38.751Z,
_id: 5ec262de5829f081b1ea96d7,
product: 5eaf8eeac436dbc9b7d75f35,
quantity: 8
},
{
date: 2020-05-18T12:11:57.168Z,
_id: 5ec27b8dd2949886308bebd6,
product: 5eaf8f61c436dbc9b7d75f36,
quantity: 6
}
]