How to determine if Angular2 component is fully loaded (including ViewChild) when there is ngIf in the template

Is it possible to identify whether the Angular2 component (here AppComponent) is fully loaded (including ViewChild) when in the ngIf template, which conditionally loads the child element.

Ref: Angular 2 @ViewChild annotation returns undefined This example is taken from the above help. Thanks kenecaswell

import {Component, ViewChild, OnInit, AfterViewInit} from 'angular2/core'; import {ControlsComponent} from './child-component-1'; import {SlideshowComponent} from './slideshow/slideshow.component'; @Component({ selector: 'app', template: ` <div *ngIf="controlsOn"> <controls ></controls> <slideshow></slideshow> </div> `, directives: [SlideshowComponent, ControlsComponent] }) export class AppComponent { @ViewChild(ControlsComponent) controls:ControlsComponent; @ViewChild(SlideshowComponent) slide:SlideshowComponent; controlsOn:boolean = false; ngOnInit() { console.log('on init', this.controls); // this returns undefined } ngAfterViewInit() { console.log('on after view init', this.controls); // this returns null } } 

ngOnInit && ngAfterViewInit are launched before loading child components due to the ngIf condition

I need to determine when SlideshowComponent and ControlsComponent are loaded, and perform an action based on this.

I have a hacker solution that doesn’t work when there are several ViewChilds (which have a different type) - Using an event emitter to inform when a child is loaded.

I am posting this question because there was no right solution after several hours of research.

+7
javascript angularjs angular angularjs-components
source share
2 answers

Plunker

Try ViewChildren instead of ViewChild which provides changes Observable, we can use it as a hook.

To track all ViewChildren, you can combine their changes Observables into one and subscribe to it, then you will get a single point of action, for example,

  @ViewChildren(ChildCmp) children: QueryList<ChildCmp>; @ViewChildren(AnotherChildCmp) anotherChildren: QueryList<ChildCmp>; childrenDetector: Observable<any>; // merged observable to detect changes in both queries ngAfterViewInit(){ this.childrenDetector = Observable.merge(this.children.changes, this.anotherChildren.changes) this.childrenDetector.subscribe(() => { // here you can even check the count of view children, that you queried // eg: if(this.children.length === 1 && this.anotherChildren.length === 1) { bothInitialized(); } // or something like that alert('you just initialized a children'); }); } } 
+1
source share

You can wrap stuff in * ngIf so that html doesn't show anything until ngOnInit has finished everything.

 <div *ngIf="loaded"> /* all codes go here */ <div> OnInit(){ foo(); bar(()=>{ this.loaded = true; }); } 
+1
source share

All Articles