How to use @ViewChild with *ngIf in Angular18+

How to use @ViewChild with *ngIf in Angular18+

When working with Angular, you may need to use the *ngIf directive to conditionally render components. However, if you try to access a view child using @ViewChild that is hidden by *ngIf, you may run into issues. In this article, we'll look at how to use @ViewChild with *ngIf in Angular.

The problem

When you use *ngIf to conditionally render a component, Angular will create or destroy the component based on the condition. If you have a view child that depends on this component, you may run into issues trying to access the view child.

Here's an example of how you might define a view child for a component with *ngIf:

@Component({
  selector: 'app-my-component',
  template: `
    
` }) export class MyComponent implements AfterViewInit { @ViewChild('myTabs', { static: false }) myTabs!: TabsetComponent; ngAfterViewInit() { console.log(this.myTabs); } }

In this code, we have a TabsetComponent inside an *ngIf directive. We use @ViewChild to define a view child for the TabsetComponent. In the ngAfterViewInit hook, we try to access the view child.

However, if showTabs is false, the TabsetComponent won't exist in the DOM, and we'll get a undefined value for myTabs.

Read, How To Implement Role-Based Access Control With JWT-Based Authorization In Angular

The solution

To handle the *ngIf condition and ensure that the view child is properly initialized, we can use a setter method with the @ViewChild decorator. Here's an updated version of our MyComponent:

@Component({
  selector: 'app-my-component',
  template: `
    
` }) export class MyComponent implements AfterViewInit { private _myTabs?: TabsetComponent; @ViewChild('myTabs', { static: false }) set myTabs(value: TabsetComponent) { if (value) { this._myTabs = value; console.log(this._myTabs); } } ngAfterViewInit() { console.log(this._myTabs); } }

In this code, we define a private property _myTabs to store the TabsetComponent instance. We use a setter method with the @ViewChild decorator to set this property when the TabsetComponent is initialized.

Inside the setter method, we check whether value is truthy before assigning it to _myTabs. This ensures that we don't try to access the view child before it's fully initialized.

In the ngAfterViewInit hook, we can access the _myTabs property and use it as needed.

Also read, Optimize Page Load Speed With Lazy Loading Images In Angular 15

Conclusion

Using @ViewChild with *ngIf in Angular can be a bit tricky, but by using a setter method, we can handle the condition and ensure that the view child is properly initialized.

Subscribe to our Newsletter

Stay up to date! Get all the latest posts delivered straight to your inbox.

If You Appreciate What We Do Here On TutsCoder, You Should Consider:

If you like what you are reading, please consider buying us a coffee ( or 2 ) as a token of appreciation.

Support Us

We are thankful for your never ending support.

Leave a Comment