1

I have a structure like this:

let MainItem = [
 {
    "Id": "1",
    "Cost": "1000"
  },
  {
    "Id": "2",
    "Cost": "5000"
  },
  {
    "Id": "3",
    "Cost": "2000"
  },
  {
    "Id": "4",
    "Cost": "3000"
  }
];

I am going to change the value of Cost each of the elements with map() loop and store it in NewMainItem.

let NewMainItem = MainItem.map((item, i) => {
  item.cost = item.cost + 1000
  return item
});

console.log(MainItem)
console.log(NewMainItem)

The main problem is that by changing Cost in NewMainItem, the value of Cost in MainItem will be changed too, but I don not want to do this. By using map() loop why the main object (MainItem ) will be changed too?

lealceldeiro
  • 14,342
  • 6
  • 49
  • 80
Sahar
  • 109
  • 2
  • 8
  • 1
    Deep clone the `item` within the `map` callback. – zero298 Oct 18 '19 at 13:46
  • @adiga I'd say [Why does map mutate array of objects?](https://stackoverflow.com/q/50990321/691711) is an even better target since that question and this do not seem to understand that the item in the iteration callback ***is*** the actual item. – zero298 Oct 18 '19 at 13:52
  • here `item.cost = ...` you change the property of an existing object. Wether you do that inside a loop, or wherever, **you change** the object. – Thomas Oct 18 '19 at 13:53

2 Answers2

1

You could assign a new object with the wanted changed value.

var mainItem = [{ Id: "1", Cost: "1000" }, { Id: "2", Cost: "5000" }, { Id: "3", Cost: "2000" }, { Id: "4", Cost: "3000" }],
    newMainItem = mainItem.map(item => Object.assign({}, item, { Cost: +item.Cost + 1000 }));

console.log(mainItem);
console.log(newMainItem);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

You should use map to create new objects from the existing ones, not modify them.

You could use the spread operator to create a new item like this:

{ ...item, Cost: parseFloat(item.Cost) + 100 };

Here parseFloat was used because the Costs values are set as string in your snippet. Feel free to change this as it fits your needs.

See below snippet:

let MainItem = [
 {
    "Id": "1",
    "Cost": "1000"
  },
  {
    "Id": "2",
    "Cost": "5000"
  },
  {
    "Id": "3",
    "Cost": "2000"
  },
  {
    "Id": "4",
    "Cost": "3000"
  }
];

let NewMainItem = MainItem.map((item, i) => {
  return { ...item, Cost: parseFloat(item.Cost) + 100 };
});
console.log(MainItem)
console.log(NewMainItem)
lealceldeiro
  • 14,342
  • 6
  • 49
  • 80