I know that arrayUnion doesnt accept duplicates, but is there anyway I could prevent that and update just one field (quantity) if the item is duplicate? Maybe you have another idea of how to structure my data in order to achieve this if a solution for this doesnt exist. Thank you
and here is the function where I try to do that (ofc this doesnt work because async):
const addProductToCart=async()=>{
const q = query(collection(db, "carts"), where("userUID", "==", user?.uid));
const docRef = await getDocs(q);
if(docRef.docs[0].exists){
console.log('not empty');
let products=docRef.docs[0].data().products;
products.forEach((product)=>{
//product exists
if(product.productUniqueName == uniqueProductName){
//console.log(product)
let cloneProduct=product;
let updateProduct=product;
updateProduct.quantity=product.quantity 1;
console.log('Updated product' updateProduct);
const currentUserCart=doc(db, 'carts', docRef.docs[0].id);
updateDoc(currentUserCart, {
cartItems: cartItems 1,
products: arrayRemove(cloneProduct),
products: arrayUnion(updateProduct)
});
return;
}
})
//productUniqueName
let newProduct={};
newProduct.productName=product.name;
newProduct.productBrand=product.brand;
newProduct.price=product.price;
newProduct.size=product.quantity;
newProduct.quantity=1;
newProduct.productUniqueName=uniqueProductName;
newProduct.img=productImages[0];
const currentUserCart=doc(db, 'carts', docRef.docs[0].id);
await updateDoc(currentUserCart, {
cartItems: cartItems 1,
products: arrayUnion(newProduct)
});
}
else{
console.log('empty');
}
}
CodePudding user response:
There isn't any direct way to do so. You'll have to read the document, check if the item already exists in that array, if it does then increment quantity and update the whole array back. If not then you can add it in the array.
I'm not sure if you fetch existing cart information to show that to user. If you do so on initial load then you can check it directly from local state (where Cart info is stored) and update accordingly.
CodePudding user response:
Ok so, I think I found an workaround: here is the code for the function and it works as expected:
const addProductToCart=async()=>{
const q = query(collection(db, "carts"), where("userUID", "==", user?.uid));
const docRef = await getDocs(q);
if(docRef.docs[0].exists){
console.log('not empty');
//added boolean to check if product exists/or not
let productFound=false;
let products=docRef.docs[0].data().products;
let currentCartItems=docRef.docs[0].data().cartItems;
products.forEach((product)=>{
//product exists
if(product.productUniqueName == uniqueProductName){
productFound=true;
let updateProduct={...product};
updateProduct.quantity=product.quantity 1;
console.log('Updated product' updateProduct);
const currentUserCart=doc(db, 'carts', docRef.docs[0].id);
//did Union and Remove separately
updateDoc(currentUserCart, {
cartItems: currentCartItems 1,
products: arrayRemove(product)
});
updateDoc(currentUserCart, {
products: arrayUnion(updateProduct)
});
//return;
}
})
//productUniqueName
if(productFound==false){
console.log('product Not found')
let newProduct={};
newProduct.productName=product.name;
newProduct.productBrand=product.brand;
newProduct.price=product.price;
newProduct.size=product.quantity;
newProduct.quantity=1;
newProduct.productUniqueName=uniqueProductName;
newProduct.img=productImages[0];
console.log('New Product', newProduct);
const currentUserCart=doc(db, 'carts', docRef.docs[0].id);
await updateDoc(currentUserCart, {
cartItems: cartItems 1,
products: arrayUnion(newProduct)
});
}
setCartItems(cartItems 1);
}
else{
console.log('empty');
}
}