0

I want to change the quantity value of a certain object in my cart array. Each object in cart array have (id, item_id, quantity, name, price).

But when my map function find that specific cart, instead of changing only quantity of that object, it replaces the whole object with the quantity value.

Please tell me what I am doing wrong.

action.payload

{
    id: "a6e1868f-e1bc-4180-abc6-328fdd8e922f",
    quantity: 7
}
state.cart.map(cartItem => cartItem.id === action.payload.id ? cartItem.quantity = action.payload.quantity : cartItem)

enter image description here

5 Answers 5

1

state.cart.map(cartItem => cartItem.id === action.payload.id ? cartItem.quantity = action.payload.quantity : cartItem)

when you return some element say x at some index from callback of map, the corresponding element which was being mapped is replaced with this x, that is how map works.

You are returning this:

cartItem.quantity = action.payload.quantity // btw don't mutate state items like this

let x;
console.log(x=9); // logs 9

console.log([1,2].map(y=>y=9)) // logs [9,9]

You want immutable approach since you are iterating state items:

let newVal=99;

let res = [{
    a: 1,
    b: 2
}].map(cartItem => 
    cartItem.a === 1 ? {
        ...cartItem,
        quantity: newVal
    } : cartItem
);

console.log(res)

Sign up to request clarification or add additional context in comments.

Comments

1

You can use spread operator to copy all the properties of item object, and then, you can replace quantity with action.payload.quantity

let cartItem = {
  id: "a6e1868f-e1bc-4180-abc6-328fdd8e922f",
  quantity: 5
}

let action = {
  payload: {
    id: "a6e1868f-e1bc-4180-abc6-328fdd8e922f",
    quantity: 7
  }
}

let cart = [cartItem]

let result = cart.map(item=>{
  if(item.id === action.payload.id){
    return {...item, quantity: action.payload.quantity};
  } else{
    return item;
  }
})

console.log(result)

1 Comment

@g-moniava Yeah, I forgot about that. Updated the code. Thanks
0

The main issue is that you are using arrow functions "without a body" (in other words, without using {}). This means that your arrow function is implicitly returning the resulting value of any expression succeeding the => symbol. In this case it will be action.payload.quantity or cartItem depending if the item ID is matched or not.

Additionally, I assume that you are using the result of the map operation (a new array with the returned items) to update your state.

If you are using Redux Toolkit or something else to ensure immutability (I assume you do because your code however is not respecting immutability as inner items are being returned as references and not as new values), you could replace your map function with a for loop or other loop structure (like Array.prototype.find) that allows you to interrupt the loop after finding the item you was looking for.

If you want to fix your code and leave it as it is (not recommended), you can do as follows:

state.cart.map(cartItem => {
  if (cartItem.id === action.payload.id) {
    cartItem.quantity = action.payload.quantity;
  }

  return cartItem;
});

Comments

0

There are some problems in

previous:  state.cart.map(cartItem => cartItem.id === action.payload.id ? cartItem.quantity = action.payload.quantity : cartItem)

you can check this:

correct:   state.cart.map(cartItem => cartItem.id === action.payload.id ? {...cartItem,quantity:action.payload.quantity} : cartItem)

Comments

0

Lets look at how Map function works:

Map function gets an Array .. goes through it while using function you define to map every element of 1st array to 2nd (new array).

You return just a number if id's are same so new element of new array will be just number:

|are id's same| ? YEP return number : NOPE return <object>

It should be:

|are id's same| ? YEP return <object> : NOPE return <object>

Fix of original code:

state.cart.map(cartItem => cartItem.id === action.payload.id ? { ...cartItem, quantity: action.payload.quantity} : cartItem)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.