TypeError: Cannot assign to read only property 'quantity' of object '#<Object>'

Viewed 4310

I'm trying to modify the field quantity of obj meal in the array orderedList. This is the error:


TypeError: Cannot assign to read only property 'quantity' of object '#'


How I can change this state.


Please help.Please help.Please help.Please help.Please help.Please help.Please help. Please help.Please help.Please help.Please help.Please help.Please help.Please help.


import {createSlice} from "@reduxjs/toolkit";

const menuList = [
    {
        id: 'm1',
        name: 'Sushi',
        description: 'Finest fish and veggies',
        price: 22.99,
        quantity: 0
    },
    {
        id: 'm2',
        name: 'Schnitzel',
        description: 'A german specialty!',
        price: 16.5,
        quantity: 0
    },
    {
        id: 'm3',
        name: 'Barbecue Burger',
        description: 'American, raw, meaty',
        price: 12.99,
        quantity: 0
    },
    {
        id: 'm4',
        name: 'Green Bowl',
        description: 'Healthy...and green...',
        price: 18.99,
        quantity: 0
    },
];

const initialStateMeals = {
    menuList,
    orderedList: [],
    numberOfOrderedMeals: 0,
    showCart: false,
    totalAmount: 0
}

const counterSlice = createSlice({
    name: 'meals',
    initialState: initialStateMeals,
    reducers: {
        add(state, action) {
            state.numberOfOrderedMeals += +action.payload.input;
            let totalAmountTemp = state.totalAmount + action.payload.meal.price * action.payload.input;
            state.totalAmount = +totalAmountTemp.toFixed(2);

            let mealIsInList = state.orderedList.filter(meal => meal.id === action.payload.meal.id).length > 0;

            if (!mealIsInList) {
                state.orderedList.push(action.payload.meal);
                state.orderedList.filter(meal => meal.id === action.payload.meal.id)[0].quantity = 1;
                //on this line I have this error
                //TypeError: Cannot assign to read only property 'quantity' of object '#<Object>'
            } else {
            }
        },
        remove(state, action) {
            state.numberOfOrderedMeals -= +action.payload.input;
        }
        ,
        closeCart(state) {
            state.showCart = false;
        }
        ,
        showCart(state) {
            state.showCart = true;
        }
    }
});

export default counterSlice.reducer;
export const mealsAction = counterSlice.actions;
1 Answers

My guess here is that redux-toolkit is protecting you from mutating the action's payload object as this mutation could leak out into any other reducer listening for the same action.

Instead of pushing into the array, and then iterating it again just to find the element you pushed, which will be the last element in the array, BTW, you could just create a new object with the properties you want and push this into the array instead.

if (!mealIsInList) {
  state.orderedList.push({
    ...action.payload.meal,
    quantity: 1,
  });
}
Related