Angular 2 life cycle hook after all children are initialized?

I ended up using the ngAfterViewInit() hook in the following way:

ngAfterViewInit(){
  //stuff that doesn't do view changes
  setTimeout(_=> this.methodThatKicksOffAnotherRoundOfChanges());
}

This should be safe to use compared to other invocations of setTimeout where an actual time is set, since it should start instantly (and just affect the threading/context behaviour)


If you need your Parent Component to await custom asynchronous behaviour across multiple child components then here's a good solution I cooked up.

Any child component's that initialise asynchronously extend this:

import {Subject} from 'rxjs/Subject';
import {Observable} from 'rxjs/Observable';

export class AsynchronouslyInitialisedComponent {
  loadedState: Subject<boolean> = new Subject<boolean>();
  loadedState$ = this.loadedState.asObservable();
  constructor() {
  }
  protected componentLoaded() {
    this.loadedState.next(true);
  }
}

Example Child component:

import {Component} from '@angular/core';
import {AsynchronouslyInitialisedComponent} from './../base_component';

@Component({
  moduleId: module.id,
  selector: 'child'
})
export class Child extends AsynchronouslyInitialisedComponent {
  constructor() {
    super();
  }
  ngOnInit() {
    //Some async behavoir:
    setTimeout(() => {
      this.componentLoaded();
    }, 10000);
  }
}

Now all your Parent component needs to do is the following:

import {Component, ViewEncapsulation, ViewChild};
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/zip';

@Component({
  moduleId: module.id,
  selector: 'parent'
})
export class Parent { 

  @ViewChild('child') child; //Just use <child #child></child> in your template

  constructor() {
  }
  ngOnInit() {
    Observable
    .zip(this.child.loadedState$, this.otherChild.loadedState$) //Add as many as you want here... 
    .subscribe(pair => {
      console.log('All child components loaded');
    });
  }
}

If you also have content children (transcluded using <ng-content>) then ngAfterContentInit() is the right lifecycle callback.

https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#aftercontent

ngAfterContentInit() {
  doSomething();
}

Tags:

Angular