0

I have 2 properties declared like so:

ngOnInit() {
this.defaultRequirements = myData.property1.countryDocument; //should never change
this.filteredRequirements = myData.property1.countryDocument; 
}

When I run this onFilter function, the defaultRequirements property also gets mutated.

onFilter(selectedSections) {
    let index = -1;

    this.defaultRequirements.forEach(country => {
      index++;
      const filteredSectionsList = [];

      country.section.forEach(section => {
        selectedSections.value.forEach(selectedSelection => {
          const selection = selectedSelection.split(/\s*[-]\s*/);  

          if (country.countryCode === selection[0]) {
            console.log('matched');
            filteredSectionsList.push(section);
          }
        });

        const countryObj = Object.assign({}, country, {
          section: [...filteredSectionsList]
        })

// Here is the issue, when filtering, this.defaultRequirements also gets changed!
        this.filteredRequirements[index] = countryObj;


      })
    })

}

The Problem

I don't understand how mutating this.filteredRequirements is ALSO mutating this.defaultRequirements (they both equal the same thing)! How can I avoid this behaviour and have defaultRequirements be unaffected by changes done on filteredRequirements?

Kode_12
  • 4,506
  • 11
  • 47
  • 97

2 Answers2

1

Try this:

ngOnInit() {
    this.defaultRequirements = JSON.parse(JSON.stringify(myData.property1.countryDocument));   
    this.filteredRequirements = JSON.parse(JSON.stringify(myData.property1.countryDocument));
}

or

ngOnInit() {
    this.defaultRequirements = {...myData.property1.countryDocument}
    this.filteredRequirements = {...myData.property1.countryDocument}
}
mojtaba ramezani
  • 1,461
  • 16
  • 15
1

Okay, so your declared object myData.property1.countryDocument is a non-primitive/reference value. So that means that both this.defaultRequirements and this.filteredRequirements are pointing to literally the same piece of data.

If you were to do this with a primitive value (eg: a string), you would get a copy; so this.defaultRequirements and this.filteredRequirements would be completely separate and could be manipulated with no effect on each other.

To duplicate/copy an object in the way that you intended is totally possible and there's been a lot of discussion about it already which I won't duplicate; I'd suggest you take a look at this which covers it nicely.

Sternjobname
  • 740
  • 1
  • 10
  • 23