Angular v8 - @ViewChild static true or false
Asked Answered
S

3

17

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???

Saucier answered 9/7, 2019 at 12:5 Comment(0)
S
40

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

Saucier answered 1/8, 2019 at 13:43 Comment(2)
I would like to correct that for the case of @ContentChild the non-static is available in ngAfterContentInitRoxie
What's the downside of the old @ViewChild than the new @ViewChild? I feel the previous one is more helpful than in today's updateVaisya
B
5

From the documentation:

How do I choose which static flag value to use: true or false?

In the official API docs, we have always recommended retrieving query results in ngAfterViewInit for view queries and ngAfterContentInit for content queries. This is because by the time those lifecycle hooks run, change detection has completed for the relevant nodes and we can guarantee that we have collected all the possible query results.

Most applications will want to use {static: false} for the same reason. This setting will ensure query matches that are dependent on binding resolution (e.g. results inside *ngIfs or *ngFors) will be found by the query.

There are rarer cases where {static: true} flag might be necessary (see answer here).

https://angular.io/guide/static-query-migration

Benjaminbenji answered 9/7, 2019 at 12:11 Comment(1)
Thanks for this, but can you please write an answer, with explanations. And not just copy-n-paste a part of the documentation.Saucier
L
0

When to use {static:true}

https://angular.io/guide/static-query-migration#should-i-use-static-true

This explains in very simple terms.

Louvenialouver answered 20/6, 2021 at 18:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.