Angular 2/3/4/5: change detection on data-bound array push/unshift, pop/shift or splice

Suppose you have a component and have bound an array variable to an input property, like so:

<myComponent [arrayInput]="myArray"></myComponent>

Suppose you were to modify the contents of myArray via its standard array methods such as push(x), pop(), unshift(x), shift(), or splice(i, c). You may notice that myComponent does not get its Input set() method called, or ngOnChanges for any component-wide changes in observed variables.

The reason is simple: the value being observed, i.e. the reference in memory of the bound array, doesn’t change. The observed value is a reference to a place in memory that stores the array. No new array is created and the reference does not change when using standard array methods. When using push, pop, etc. the array is modified in place.

A quick way outside of importing more Angular overhead such as ChangeDetection is to simply recreate the array for every array operation, thereby changing the reference in memory to trigger the ngOnChanges and Input set() methods in the component.

Example workarounds would be:

pushAndUpdate(x) {
  this.myArray = [...this.myArray, x];
}

popAndUpdate() {
  let x = this.myArray.pop();

  this.myArray = this.myArray.slice();
  return(x);
}

unshiftAndUpdate(x) {
  this.myArray = [x, ...this.myArray];
}

shiftAndUpdate(x) {
  let x = this.myArray.shift();

  this.myArray = this.myArray.slice();
  return(x);  
}

*     *     *

If you found this article helpful, be sure to leave a comment and take a look at some of my other work.

3 thoughts on “Angular 2/3/4/5: change detection on data-bound array push/unshift, pop/shift or splice”

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: