Angular v8 – @ViewChild static true or false

angularangular8viewchild

Angular v8 has just been released. Although it's mostly backward compatible, there's some Breaking Changes.

According to Angular's Changelog one core change is (and I quote):

"In Angular version 8, it's required that all @ViewChild and @ContentChild queries have a 'static' flag specifying whether the query is 'static' or 'dynamic'."

It's also state that in most cases just setting { static: false } will do the trick.

@ViewChild('selectorName', { static: false }) varName: any;

My question is when should I set this attribute (static) to be true? and how will it effect my application???

Best Answer

Use { static: true } when you want to access the ViewChild in ngOnInit.

Use { static: false } will be accessible only in ngAfterViewInit. This is also what you want to do for when you have a structural directive (*ngIf etc.) in your template.

In most cases { static: false } will work.

import { Component, OnInit, AfterViewInit, ViewChild, ElementRef } from '@angular/core';

@Component({
  selector: 'example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.scss']
})
export class ExampleComponent implements OnInit, AfterViewInit
{
  @ViewChild('elementA', { static: true }) elementStatic: ElementRef<HTMLElement>;
  @ViewChild('elementB', { static: false }) elementDynamic: ElementRef<HTMLElement>;
        
  public ngOnInit(): void
  {
    this.elementStatic.nativeElement; // Ok
    this.elementDynamic.nativeElement; // ERROR TypeError: Cannot read property 'nativeElement' of undefined 
  }
  
  public ngAfterViewInit(): void
  {
    this.elementStatic.nativeElement; // Ok
    this.elementDynamic.nativeElement; // Ok
  }
}
<div #elementA>A</div>
<div #elementB>B</div>

Update: Starting from Angular v9.x static has a default value of false.
Read more at: https://angular.io/api/core/ViewChild#viewchild