Reputation: 1208
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
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
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