Explosion Pills Explosion Pills - 2 months ago 13
TypeScript Question

Call ViewChild methods with updated nested value in Angular2

I am using the angular2-progressbar library to display some circular progress bars in my app. I have a list of inventory items and a service that updates the inventory list. Each inventory item component gets the updated inventory value from a key in the inventory list like so:

export class InventoryComponent implements OnInit {
@ViewChild(CircleProgressComponent): circleComp: CircleProgressComponent;
@Input() deviceKey: string;
private circleOptions: ShapeOptions { /* from angular2-progressbar example */ }
constructor(private inventoryService: InventoryService) { }
ngOnInit(): void {
this.deviceList = this.inventoryService.deviceList;
setInterval(() => {
// this value will be 0 or 1
}, 2000);

While this does work, it seems very hacky to me to have the interval check only after every 2 seconds when the actual value in the template itself gets updated immediately whenever
updates its device list.

I tried implementing
, but there are two problems:

  1. The initial
    fires before the view init lifecycle, i.e. before
    is available. This breaks things.

  2. Because
    is an object and its properties get updated internall,
    does not get fired anyway. Instead I can do an additional check using
    -- this does work, but it is a lot more verbose and #1 still causes a problem.

Is there any way to start performing checks after the view has loaded?


Is there any way to start performing checks after the view has loaded?

Use the AfterViewInit lifecycle hook (override ngAfterViewInit). This is when the @ViewChild is available

I think there may be a better solution than polling deviceList. You could use a Subject in the service. This will act like an observer and observable, so you can subscribe to it on one end, and publish on the other. For example

import { BehaviorSubject } from 'rxjs/BehaviorSubject'

class InventoryService {
  private _inventoryList = new BahaviorSubject<any>({ initialize with data })

  inventoryList$ = this._inventoryList.asObservable();

  set inventoryList(list: any) {

Now you can just subscribe to the list. And whenever you want to update it, just use the setter, and all the subscribers will get the updated list. No need to poll.


service.inventoryList$.subscribe(list => {})


service.inventoryList = newList

See also: