0

I have the method getParameters() that returns a setting object, that contains a list of parameters, i implemented code inside subscribe and i added some items in the parameters list, when i display the new object i find that the list has the added items, but the problem is that when i display the returned object i find that it changed too

this.settingService.getParameters().subscribe((setting: Setting) => {
    const settingToSave = setting;

    this.parameters.forEach(element => {
       if (settingToSave.parameters.some(parameter => parameter.parameterId === element.parameterId)) {
          settingToSave.parameters = settingToSave.parameters.filter(parameter => parameter.parameterId != element.parameterId);
       }
        settingToSave.parameters.push(element);
     });

    console.log(settingToSave);
    console.log(setting); // same content as the object settingToSave

}
Aymen Kanzari
  • 1,765
  • 7
  • 41
  • 73

2 Answers2

1

By const settingToSave = setting, you are creating a reference, not a copy. Hence, when you modify properties of settingToSave, you are modifying the same object as when modifying setting 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));

reference.property = "new value";

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

See How to Deep clone in javascript for alternatives.

fjc
  • 5,590
  • 17
  • 36
1

In many programming languages when you try to copy an object variable by doing A = B then you are copying the variable by reference and not by value. So any changes made in A will be applied to B and vice versa. If you want to copy an object variable and make changes to it without affecting its original declaration use this (ES6) :

let newObj = Object.assign({}, originalObj);

or in your case replace the line:

const settingToSave = setting; with: let settingToSave = Object.assign({}, setting);

Source used: MDN Object assign

Andreas
  • 36
  • 3
  • 1
    Your explanation is correct, I just want to warn to be careful using `Object.assign` or the spread operator (`const noRealCopy = {...original};`): When you have objects as properties, they continue to be referenced rather than copied. Example: https://www.typescriptlang.org/play/#code/MYewdgzgLgBCBOBLA5osBDANjAvDA3sABaKYAmA8gEYBWApsFAFwEBExpZACvCAA514UAJ6sW7EuQBqWAK51WAX0UBuGAChQkWKD7DcBAHTGEKNFlUbdwwx3LV6jW5O68BQ-XgDkYOgHcAYRcZTHkvNU1wCBBMOkNMEGQACmtnTgcGKDTyHn5BEVwcPFNUDExsylpMitz3EQBKFSA – fjc Jul 08 '19 at 13:04