I want to explain the use case i have so you can understand it well
I have Cart & Products when the user adds the product (product_id = 1) twice to the cart and the product has the same options (red, xl) I increment the quantity,
if the user adds the same (product_id = 1) but with other options (green, xl), I add this product to the cart as a separate product.
Now this works well!
but when the user after added the above 2 products and add the same product with the same option (red, xl) again, It's added as a separated product!
What I expected if the product options existing before should increment the quantity otherwise added it as a separate.
What i tried
add the option ids into the Product property and check if it exists before or not then handle what I want but it does not work well and added the third product as a separate one!
code snippet
zustand Store
interface CartProductsProp extends State { cartProducts: ProductProps[]; addToCart: (Products: ProductProps) => void; updateProductQuantity: ( Product: ProductProps, updatedQuantity: number, ) => void; checkProductOptionsExist: ( Product: ProductProps, updatedQuantity: number, ) => void; ...}export const useCartProduct = create<CartProductsProp>( persist( (set, get) => ({ cartProducts: [], addToCart: (product) => { set((prev) => ({ cartProducts: [...prev.cartProducts, {...product}], })); }, checkProductOptionsExist: ( product: ProductProps, updatedQuantity: number, ) => { set((prev) => { console.log('->prev', JSON.stringify(prev.cartProducts)); console.log('check==>IDs', cartProduct.id === product.id && product.productOptionIds === cartProduct.productOptionIds, ); // for some reason this run towic when add the third product"with same options as first product "red,xl" true then false return prev.cartProducts.map((cartProduct) => { cartProduct.id === product.id && product.productOptionIds === cartProduct.productOptionIds ? get().updateProductQuantity(product, updatedQuantity) : get().addToCart(product); }); }); }, // To Update the quantity when product exist in cart before updateProductQuantity: ( product: ProductProps, updatedQuantity: number, ) => { set((prev) => { let currentCart = prev.cartProducts.map((cartProduct) => cartProduct.id === product.id && areEqual(cartProduct.selectedOptions, product.selectedOptions) ? { ...product, quantity: cartProduct?.quantity! + updatedQuantity, updated: 'yes@', productTotalPrice: (cartProduct?.quantity! + updatedQuantity) * cartProduct.price, } : cartProduct, ); console.log('##currentCart', JSON.stringify(currentCart)); return { cartProducts: currentCart, }; }); ... }, }), { name: 'cartListProduct-local', getStorage: () => AsyncStorage, }, ),);
Product Details
const addProductToCart = () => { let productOptionIds = allOptions .map(({id}: {id: number | string}) => id) .sort() .join(','); let currentProduct = { ...item, id: item.id, product_id: item.id, quantity: currentQuantity, price: updatedPrice, productTotalPrice: updatedPrice * currentQuantity, selectedOptions: allOptions, productOptionIds: productOptionIds, }; setAddToCartLoading(true); if ( !cartProductList.some((alreadyExist) => alreadyExist.id === item.id) ) { addToCart(currentProduct); Alert.alert(t('addedSuccessfully')); setAddToCartLoading(false); } else { checkProductOptionsExist(currentProduct, currentQuantity); Alert.alert(t('addedSuccessfully')); } };
Utility
export const areEqual = (a: arrayProps = [], b: arrayProps = []): boolean => { // compare length of arrays if (a.length !== b.length) { return false; } // get ids set in b const idsSetInB = new Set(b.map(({id}: {id: number | string}) => id)); console.log('idsSetInB', idsSetInB); // iterate over a, and check if the id of an item is not in b for (let {id} of a) { if (!idsSetInB.has(id)) { return false; } } // if it passes all the items, return true return true;};