Add Same Product with different sizes and prices to the cart

140 views Asked by At

I can add different products as individual arrays and I can also increase and decrease the quantities if the same product added. But I would want to add same product with different size. Below is my code.. Please help out..!

Context screen:

 const initialState = {
  
  products: ProductData,
    cart: [],
  };
 
const reducer = (state = initialState, action)=>{
    switch(action.type){
        case 'ADD':
            const item = state.products.find(
                (product) => product.id === action.payload.id
              );
              // Check if Item is in cart already
              const inCart = state.cart.find((item) =>
                item.id === action.payload.id ? true : false
              );
        
              return {
                ...state,
                cart: inCart
                  ? state.cart.map((item) =>
                      item.id === action.payload.id
                        ? { ...item, qty: item.qty + 1 }
                        : item
                    )
                  : [...state.cart, { ...item, qty: 1 }],
              };
            
        case 'DELETE':
        return {
            ...state,
            cart: state.cart.filter((item) => item.id !== action.payload.id),
          };
       
        case 'INCREASE':
               const tempCart = state.cart.map((cartItem) => {
                if (cartItem.id === action.payLoad.id) {
                  return { ...cartItem, qty: cartItem.qty + 1 };
                }
                return cartItem;
              });
              return { ...state, cart: tempCart };
        
        case 'DECREASE':
                const temp = state.cart.map((cartItem) => {
                    if (cartItem.id === action.payLoad.id) {
                      return { ...cartItem, qty: cartItem.qty - 1 };
                    }
                 return cartItem;
                  })
                  .filter((cartItem) => cartItem.qty !== 0);
                return { ...state, cart: temp };
              
        case 'CLEAR':
              return {cart :[]}
           
        default:
            throw new Error(`unknow action.${action.type}`)
    }

}

Product Data

 export const ProductData = [
{
  id: 'C1',
  name:'Coffee',
  categories: [1],
  price: 15.00,
  prices: [
    {size: 'S', price: '1.38', currency: '$'},
    {size: 'M', price: '3.15', currency: '$'},
    {size: 'L', price: '4.29', currency: '$'},
  ],
 
{
  id: 'C2',
  name: "Coffee",
  icon:icons.coffee_1,
  categories: [1,2],
  price: 15.00,
  prices: [
    {size: 'S', price: '1.38', currency: '$'},
    {size: 'M', price: '3.15', currency: '$'},
    {size: 'L', price: '4.29', currency: '$'},
  ],

} ]

I can add, delete, increase and decrease but I wanna add same product to the cart with different specification. your help is highly appreciate.

2

There are 2 answers

4
Anshu On BEST ANSWER

Modify your action.payload from {id:''} to {id:'',size:''}.

case 'ADD':
  const newItem = { ...action.payload, qty: 1 };
  const existingItemIndex = state.cart.findIndex(
    (item) => item.id === action.payload.id && item.size === action.payload.size
  );

  if (existingItemIndex !== -1) {
    // Product with the same specifications is already in the cart, increment quantity
    const updatedCart = state.cart.map((item, index) =>
      index === existingItemIndex ? { ...item, qty: item.qty + 1 } : item
    );

    return { ...state, cart: updatedCart };
  } else {
    // Product with different specifications or not in the cart, add a new item
    return { ...state, cart: [...state.cart, newItem] };
  }
1
Prabakar On

Just add some flag to maintain the selected price in prices array for each (either you can keep it all false or keep one size as default)

prices: [
    {size: 'S', price: '1.38', currency: '$', isSelected: false },
    {size: 'M', price: '3.15', currency: '$', isSelected: true },
    {size: 'L', price: '4.29', currency: '$', isSelected: false },
  ]

When user makes selection and click on add product to cart, you can pass the product to state with respective size's flag updated as true


  case 'ADD':
      const selectedPrice = action.payload.prices.find(sp => sp.isSelected)
      
      const productItem = products.find(
        (product) => product.id === action.payload.id
      );

      // Check if Item is in cart already
      const inCart = state.cart.find((item) => {
        const cartSelectedPrice = item.prices.find(sp => sp.isSelected);
       
        const sizeExists = selectedPrice && cartSelectedPrice && 
                           selectedPrice.size === cartSelectedPrice.size;

        return item.id === action.payload.id && sizeExists ? true : false
        }        
      );

       return {
           ...state,
           cart: inCart
              ? state.cart.map((item) =>
              item.id === action.payload.id
                 ? { ...item, qty: item.qty + 1 }
                  : item
                 )
                 : [...state.cart, { ...productItem , qty: 1 }],
           };