Anoop K George
Anoop K George

Reputation: 1735

React-Redux, error in filtering out item from store

I have a e-commerce store when user click on add item to cart, it add to redux store.

I have a checkout page where it lists all added item, if user click on remove item, it should be removed from store. Each item in checkout page have key as uuid.

I am using uuid to keep unique id for items when added to cart.

Suppose I have 2 items in cart , if user click delete in out item , it dispatches uuid of the item to store,

const initialState = {
    items: []
  };
  
  const cart = (state = initialState, action) => {
    switch (action.type) {
    ...
      case "DELETE": {
        return {
         
          items: [
            state.items.filter((item) => {
              item.uuid !== action.payload;
            }),
          ],
        };  
    ...
  };
  export default cart;

But after this all my cart items gets deleted and get warning in console that all items should have unique id.

Each item in state consists of below kind objects,

  [{uuid: "uniqueid_1", name:'first'},{uuid: "uniqueid_2", name:'first'}]

  I dispatches an remove action consists of payload as uuid (ie,"uniqueid_1")

The complete code reference below,

Action

import { v4 as uuidv4 } from "uuid";

const add = (item, quantity) => {
  return {
    type: "ADDTOCART",
    payload: {
      uuid: uuidv4(),
      id: item.id,
      image: item.photo,
      name: item.name,
      price: item.price,
      quantity: quantity,
    },
  };
};

const remove = (item) => {
  return {
    type: "DELETE",
    payload: item,
  };
};

const removeall = () => {
  return {
    type: "REMOVEALL",
  };
};

export default { add, remove, removeall };

REDUCER


const initialState = {
  items: [],
};

const cart = (state = initialState, action) => {
  switch (action.type) {
    case "ADDTOCART": {
      return { items: [...state.items, action.payload] };
    }
    case "DELETE": {
      return {
        
        items: [
          state.items.filter((item) => {
            item.uuid !== action.payload;
          }),
        ],
      };
    }
    case "REMOVEALL": {
      return { items: [] };
    }
    default:
      return state;
  }
};

export default cart;

REMOVE ACTION

 onClick={() => {dispatch(cartAction.remove(product.uuid));}}
                    
                  

Upvotes: 0

Views: 239

Answers (3)

Anoop K George
Anoop K George

Reputation: 1735

I have removed curly braces from filtering and it worked

 items: [
          state.items.filter((item) => 
            item.uuid !== action.payload;
          ),
        ],
      

Upvotes: 0

Add the Spread Syntax(...) here:

 items: [
          ...state.items.filter((item) => {
            item.uuid !== action.payload;
          })
],

because this:

[{uuid: "uniqueid_1", name:'first'},{uuid: "uniqueid_2", name:'first'}].filter(x=>x.uuid!=="uniqueid_1")

return an array. your items array it inside another array at the end, like this:

[[{uuid: "uniqueid_1", name:'first'}]]

And you need this:

[{uuid: "uniqueid_1", name:'first'}]

Upvotes: 1

Gegenwind
Gegenwind

Reputation: 1428

Your mistake could be that you now have an array too much. You can change it to:

const initialState = {
    items: []
  };
  
  const cart = (state = initialState, action) => {
    switch (action.type) {
    ...
      case "DELETE": {
        return {
         
          items: 
            state.items.filter((item) => {
              item.uuid !== action.payload.uuid;
            }),
        };  
    ...
  };
  export default cart;

This is because state.items.filter will already return an array of objects, so you don't need to wrap it in []

Also Due to the fact that you are using the item as payload for the delete action you need to use item.uuid !== action.payload.uuid for comparison

Upvotes: 2

Related Questions