0

there's my problem:

I've a function that add a element to a array (A), the element to add comes from the argument. Then when I modify this element in the array (A), it also modify the element that I used as argument.

it look like that :

addTemplates(nTemplate){
    let k = nTemplate;
    k.id=this.templates.length+1;
    this.templates.push(k);
    this.emitTemplateSubject();
  }
  
  //when I use the function:
  
  let aObject={id:1, sth:"aa", sthE:"bb"}
  addTemplate(aObject);
  
  
  //then  aObject.id is also change.

It's probably normal but how can I avoid to apply the changement on 'aObject' ?

1
  • 1
    Most of the answers you will get will recommend you various ways to create a shallow clone of your object. Assuming that your objects will not all be as simple as the one in your question, you'd probably be better off looking into deep cloning of JavaScript objects. TL;DR: In my personal opinion, importing lodash's cloneDeep() method is the simplest and most robust solution for Angular. Commented Jul 9, 2019 at 8:43

4 Answers 4

2

You have to create a copy of your object and then send it to the function

let newObject = Object.assign({}, aObject);
addTemplate(newObject );

This is because when you are passing the object, it is passing as a reference. What you need is to pass as data for that you need to create a copy of your object and send it to function.

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

1 Comment

Note that when using the spread operator on an object that has objects as properties, those objects will be referenced: const aObject={child:{"property":"value"}}; const spread = {...aObject}; spread.child.property = 'new value'; console.log(aObject.child.property === spread.child.property);
1

With this.templates.push(k);, you add a reference, not a copy, of kto templates. Hence, when you modify properties of the reference in the array, you are modifying the same object as when modifying k directly.

A simple example that shows the difference between a reference and a copy (in this case, I am creating a copy using JSON.parse(JSON.stringify(...)), which I would not recommend for actual real-life projects):

const original = {"property":"value"};
const reference = original;
const copy = JSON.parse(JSON.stringify(original));

const array = [reference, copy];

array[0].property = 'new value for reference';
array[1].property = 'new value for copy';

console.log(reference.property === original.property);
console.log(copy.property !== original.property);

If you have a shallow object, you can simply use the spread operator (this.templates.push({...k});) to create a copy.

If you have objects as properties of k, which would mean that they would be referenced in the copy, you'd need to deep-clone k.

Comments

0

You can use the spread operator and have something like:

let aObject={id:1, sth:"aa", sthE:"bb"}
addTemplate({... aObject});

1 Comment

Note that when using the spread operator on an object that has objects as properties, those objects will be referenced: const aObject={child:{"property":"value"}}; const spread = {...aObject}; spread.child.property = 'new value'; console.log(aObject.child.property === spread.child.property);
0

You could try something like below and use assign keyword for creating new objects instead of assigning refrence.

let aObject = {
  id: 1, sth: "aa", sthE: "bb"
}
addTemplates(aObject);


function addTemplates(nTemplate) {
  let k  = Object.assign({}, nTemplate);
  k.id=this.templates.length+1;
  this.templates.push(k);
  this.emitTemplateSubject();
}

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.