Angular: How to use ViewChild to get component shown after AfterViewInit
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.