How to watch for changes an array/object on Angular 2

In the good old days of Angular.js we had the $scope.$watch mechanism to follow the changes in our variables. For Angular 2 all this has been changed for performance reasons.

So, you will be left wondering how to watch the changes on your array/object, needed on every application. You start googling for a solution. You will find either deprecated info or workarounds like adding an event emitter where your object is updated. No need to mention that this is not a clean solution, neither a reliable one. Let’s suppose that you have a component that receives a bind data source that you cannot control, what are the options?

So let’s do this like is supposed to be done, on our component, using the Angular directive dirty check life-cycle hook DoCheck and¬†iterable diffing strategies¬†IterableDiffers (for arrays) or KeyValueDiffers (for objects), all of them on @Angular/core.

Our component will look like the following:

import { Component, Input, IterableDiffers, DoCheck } from '@angular/core';

@Component({
  selector: 'app-array-watch-demo',
  templateUrl: './array-watch-demo.component.html',
  styleUrls: ['./array-watch-demo.component.css']
})
export class ArrayWatchDemoComponent implements DoCheck {

  @Input() datasource: Array<any> = [];

  differ: any;

  constructor(differs: IterableDiffers) {
     this.differ = differs.find([]).create(null);
   }

  ngDoCheck() {
    const change = this.differ.diff(this.datasource);
    console.log(change);
    // here you can do what you want on array change
    // you can check for forEachAddedItem or forEachRemovedItem on change object to see the added/removed items
    // Attention: ngDoCheck() is triggered at each binded variable on componenet; if you have more than one in your component, make sure you filter here the one you want.
  }

}

Basically, here we add DoCheck() that is triggered by each bind element change and there we do a diff between the former and actual state on the variable to read the changes.

This solution works on Angular 4.2.3 (June 2017) and is not tested on earlier versions.

I added a demo app on GitHub if you want to see how it works:

https://github.com/bogdancar/angular2-array-object-change-watch-demo

2 thoughts on “How to watch for changes an array/object on Angular 2

Leave a Reply

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