0

with typescript I would like to manage a list of objects without using ngrx and with immutability.

as an example, I proceed as follows:

    let items = <any>[];
    let item1 = { n: 'toto' };
    // ADD item1
    items = [...items, item1];
    // Find item
    const item1Find = items.filter((v) => v.n == 'toto')[0];
    // update item
    item1Find.n = 'titi';
    // update item with immuability
    items = [...items, item1Find];
    //
    console.log('items', JSON.stringify(items));   // [{"n":"titi"},{"n":"titi"}]

but the problem is that I have 2 times the object that I modified!

I don't understand, can you help me please?

duke666
  • 45
  • 6
  • _"but the problem is that I have 2 times the object"_ - No, you have two references that point to the same object. – Andreas Jun 11 '21 at 10:15

1 Answers1

0

Objects and arrays are passed by reference, so unless you explicitly clone them you will always be updating the original item that they are referencing. You can think as references as being an arrow which points towards the object, but isn't the object itself. When you update a reference, you don't change the arrow, you just send the changes to where the arrow points.

In your case, item1Find is a reference to the object item1

const item1Find = items.filter((v) => v.n == 'toto')[0];

So when you then modify item1Find, you are actually modifying the underlying object that you created, e.g. item1. Creating an array of [ item1, item1Find ] is then clearly just an array whose contents will resolve to [ item1, item1 ].

This is a common gotcha in JavaScript and is well documented. The answer is you need to create a copy of the object any time you want to modify it (unless you explicitly using this reference behaviour to your advantage). 9 times out of 10 you'll want to clone the object. See this post for the best ways to do that in JavaScript based on your use case.

nate-kumar
  • 1,675
  • 2
  • 8
  • 15