Angular: How to use ViewChild to get component shown after AfterViewInit

peng37
1 min readApr 5, 2019

--

Angular doc says we should use the child component injected by ViewChild in ngAfterViewInit. But sometimes you even can’t get it in ngAfterViewInit.


Check code here.

For example, you have a child component:

@Component({
selector: 'mst-child',
template: 'child',
styles: ['']
})
export class ChildComponent {
getValue() {
return 3;
}
}

And a parent component:

@Component({
selector: 'mst-parent',
template: `<mst-child></mst-child>`,
styles: ['']
})
export class ParentComponent implements AfterViewInit {
@ViewChild(ChildComponent) child: ChildComponent;
ngAfterViewInit() {
console.log(this.child.getValue());
}
}

Everything works fine until now.

But if you do this in your parent component, it stop working:

@Component({
selector: 'mst-parent',
template: `<mst-child *ngIf="showChild"></mst-child>`,
styles: ['']
})
export class ParentComponent implements OnInit, AfterViewInit {
@ViewChild(ChildComponent) child: ChildComponent;
showChild = false; ngOnInit() {
setTimeout(() => {
this.showChild = true;
}, 1000);
}
ngAfterViewInit() {
console.log(this.child.getValue());
}
}

The reason is, the child component is not created yet when AfterViewInit hook runs.

One solution:
Create a child wrapper component, ViewChild in the wrapper, and now you can do whatever you want in the ngAfterViewInit of the wrapper:

ChildWrapperComponent:

@Component({
selector: 'mst-child-wrapper',
template: '<mst-child></mst-child>',
styles: [''],
})
export class ChildWrapperComponent implements AfterViewInit {
@ViewChild(ChildComponent) child: ChildComponent;
ngAfterViewInit() {
console.log(this.child.getValue());
}
}

ParentComponent:

@Component({
selector: 'mst-parent',
template: `<mst-child-wrapper *ngIf="showChild"></mst-child-wrapper>`,
styles: ['']
})
export class ParentComponent implements OnInit {
showChild = false;
ngOnInit() {
setTimeout(() => {
this.showChild = true;
}, 1000);
}
}

Now you are good to go.

--

--