Umair Nadeem
Umair Nadeem

Reputation: 33

JavaScript map Function replacing object

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

Upvotes: 0

Views: 3732

Answers (5)

Giorgi Moniava
Giorgi Moniava

Reputation: 28654

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)

Upvotes: 1

TechySharnav
TechySharnav

Reputation: 5084

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)

Upvotes: 1

JsonKody
JsonKody

Reputation: 717

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)

Upvotes: 0

Viktor M
Viktor M

Reputation: 301

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)

Upvotes: 0

Ernesto Stifano
Ernesto Stifano

Reputation: 3130

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;
});

Upvotes: 0

Related Questions