How to Detect Changes to an Input Array from a Child Component in Angular
Detecting changes to an array from the @Input()
directive can be tricky.
Suppose we have the following input array arr
that is bound to a getter and setter.
_arr: string[] = [];
get arr(): string[] {
return this._arr;
}
@Input() set arr(newArr: string[]) {
this._arr = newArr;
}
Properties Passed by Reference
Let’s say we have a Child
component that accepts an arr
and contains the getters and setters from above.
<Child [arr]='arr'></Child>
We’d expect arr
to update in the Child
component if we pushed to this array, but this isn’t the case. Properties that are passed by reference will not trigger the setter of this @Input()
directive. This includes mutating an object as well.
In these scenarios, we would need to update the reference passed as an input in order to trigger the setter.
Solution
We can create a new reference by merging our array with an empty array.
this.arr = ['corgi', 'shih tzu'];
this.arr.push('pug');
this.arr = [].concat(this.arr);
This solution is a constant time operation since we are simply creating a new variable that points to the same area in memory as the previous one. We aren’t cloning the contents of the array.
This means our reference changes, thereby triggering the OnChanges
mechanism in the Child
component.