The Walrus
The Walrus

Reputation: 1208

How to replace an object property value in redux

I am trying to create an online shop using redux. I have got it so that a person can add an item to their basket. However, having difficulty with adding quantity. I have a method that works that wont let someone add the same product twice, I just need to now make it increase the quantity for that same product.

My basket state is stored as an array of objects.

This is my basket reducer:

const initialState = [];

const isProductInBasket = (state, action) => {
  for (var i=0; i < state.length; i++){
    if(state[i].product.id == action.data.product.id){
      return true;
    }
  }
}

export default (state = initialState, action) => {
  switch(action.type) {
    case "ADD_TO_BASKET":
      if (isProductInBasket(state, action)) {
        for (var i=0; i < state.length; i++){
          if(state[i].product.id = action.data.product.id){
            console.log(state, 'stst');
            const basketState = state[i].product.quantity + 1;
            return {...state, basketState}; //problem is here
          }
        }
      }
      else {
        const basketState = [].concat(state).concat(action.data)
        return basketState;
        break;
      }
    default:
        return state
  };
};

Clearly what im doing is wrong as im returning an object, but im wondering how i can return that new object in place of the old object. i need to return it as an object but inside an array...

just to be uber clear, when I have this:

{name: "Rucksack", price: "15.00", id: 1, quantity: 0}

and I click add to basket, it should then come back as:

{name: "Rucksack", price: "15.00", id: 1, quantity: 1}

Upvotes: 2

Views: 2168

Answers (2)

Joe Clay
Joe Clay

Reputation: 35797

I'd recommend reading this section of the Redux docs - it shows you how to update an individual element in an array without mutation.

Effectively, what you need to do is create a new array that has a modified copy of your basket item. When you need to perform a transformation on an array without mutating, Array.prototype.map is your friend:

if (isProductInBasket(state, action)) {
    return state.map(product => {
        if (product.id == action.data.product.id) {
            return { ...product, quantity: product.quantity + 1 };
        }
        return product;
    });
}

Upvotes: 1

Shubham Khatri
Shubham Khatri

Reputation: 281656

You could use findIndex to check if the object already exists and update it else push the payload data into state

switch(action.type) {
    case "ADD_TO_BASKET":
      const index = state.findIndex(productData => productData.product.id === action.data.product.id);
     if(index > -1) {
        return [
            ...state.slice(0, index),
            {
                ...state[index],
                product: {
                    ...state.product,
                    quantity: state[index].product.quantity + 1
                }
            },
            ...state.slice(index + 1)
        ]
     } 
     return [...state, action.data]

Upvotes: 0

Related Questions