Reputation: 4033
I have a mock array inside of my caseService
, from this array data is distributed through the whole web-app.
To get the data inside of another component I use the following code:
this.cases = this.caseService.data;
It works fine, but there's one thing bothering me.
In one of my components I have an infinite scroll:
@HostListener('window:scroll', ['$event'])
scroll() {
const pos = (document.documentElement.scrollTop || document.body.scrollTop) + document.documentElement.offsetHeight;
const max = document.documentElement.scrollHeight;
if (pos === max) {
this.cases.push(...this.casesService.data);
// causes trouble
}
}
As the user scrolls, the array this.cases
is being pushed. It works fine, but when I leave this component by going back or routing somewhere else, this.cases
& even this.casesService.data
keep the amount of entries (amount depends on for how long the user scrolled) - hence every other component displays an increased amount of cases.
Reloading the page solves the issue again.
Upvotes: 1
Views: 66
Reputation: 6844
This happens because this.cases
and this.caseService.data
are different references to the same object.
To illustrate the issue:
var a = [];
var b = a;
b.push("test");
console.log(a) // ["test"]
To fix this, you need to ensure the two objects are not the same. When you set the initial value, simply clone the array:
this.cases = [...this.caseService.data];
NOTE: There are many ways to clone an array, this is just my personal preference.
Now you can freely modify this.cases
without changing this.caseService.data
.
As noted by @Rich, this will only prevent changes to the contents of the arrays. This will not prevent changes to properties of these objects.
For example:
var a = [{ name: "Original Name" }];
var b = [...this.caseService.data];
b[0].name = "Test Name";
a[0].name === "Test Name"; // True
To avoid this you would need to perform a deep clone:
this.cases = JSON.parse(JSON.stringify(this.caseService.data));
NOTE: Again, there are many ways to accomplish a deep clone, this is just my personal preference.
Upvotes: 1