@ViewChild in *ngIf

📝 Easy Guide: Using @ViewChild in *ngIf
Have you ever encountered the problem of accessing an element with @ViewChild in Angular when that element is hidden by an *ngIf directive? It can be quite frustrating, but fear not! We're here to provide you with an elegant solution to this common issue.
Let's dive right in and understand the problem. In the given code snippet, we have a component template containing a hidden div element:
<div id="layout" *ngIf="display">
<div #contentPlaceholder></div>
</div>The display variable is initially set to false, making the entire div hidden. Inside the component class, we have declared a @ViewChild variable called viewContainerRef to reference the contentPlaceholder element:
export class AppComponent {
display = false;
@ViewChild('contentPlaceholder', { read: ViewContainerRef }) viewContainerRef;
show() {
this.display = true;
console.log(this.viewContainerRef); // undefined
setTimeout(() => {
console.log(this.viewContainerRef); // OK
}, 1);
}
}The problem arises when we try to access viewContainerRef immediately after setting display to true. Due to Angular's change detection process, the view has not yet been updated, and the viewContainerRef is undefined. To circumvent this, the code uses a setTimeout function with a minimal delay of 1ms to ensure that the view is updated before accessing the viewContainerRef.
While this solution works, it may not be the most elegant approach. Invoking a setTimeout function to handle this scenario feels like a workaround rather than a proper solution. But don't worry, we have a better way!
🚀 The Elegant Solution: ngAfterViewInit
Angular's lifecycle hooks come to the rescue once again! Instead of relying on a setTimeout function, we can utilize the ngAfterViewInit lifecycle hook to ensure that the view has been fully initialized before accessing the viewContainerRef.
Here's how you can implement this solution:
export class AppComponent implements AfterViewInit {
display = false;
@ViewChild('contentPlaceholder', { read: ViewContainerRef }) viewContainerRef;
ngAfterViewInit() {
console.log(this.viewContainerRef); // OK
}
show() {
this.display = true;
}
}By implementing the AfterViewInit interface and adding the ngAfterViewInit method, we guarantee that the view has been fully initialized before accessing the viewContainerRef. This eliminates the need for the setTimeout workaround and provides a cleaner and more elegant solution to the problem.
📣 Engage With Us!
We hope this guide helped you overcome the common issue of using @ViewChild in conjunction with *ngIf directives. If you have any further questions or suggestions, feel free to reach out to us in the comments section below. Let's keep the conversation going and help each other become better Angular developers!
Take Your Tech Career to the Next Level
Our application tracking tool helps you manage your job search effectively. Stay organized, track your progress, and land your dream tech job faster.


