@ViewChild returns undefined @ViewChild returns undefined angular angular

@ViewChild returns undefined


ViewChild() works fine on latest plunker Angular version with the scenario you describe.

Demonstration in this plunker : https://plnkr.co/edit/KzWnkE5Hvp7NUow6YAxy

EDIT: Here is a replacement StackBlitz for the above Plunker: https://stackblitz.com/edit/angular-ivy-pzaglm

component :

ngAfterViewInit() {    console.log(this.testView); // correctly outputs the element in console, not undefined}
  • Check that ElementRef and ViewChild are correctly imported from '@angular/core'

  • Your element might simply not be there at the time of AfterViewInit (in case there is a *ngIf, for instance. (seems the case as per your comments)

In the latter case, you can use a wrapper element and ViewChildren , that emits some event when a new child element is added - more info on documentation here : https://angular.io/api/core/ViewChildren

note that there might be some issue with native div as per this question : @ViewChildren does not get updated with dynamically added DOM elements , but this can be worked around by using a new component that wraps your div, for instance.

EDIT

Or you can also use a timeout to wait for the component to be rendered. I must say that I find this solution 'dirty', but glad it works for you :)


However, even if you access to the child component in the AfterViewInit, sometimes the @ViewChild was still returning null. The problem can be caused by the *ngIf or other directive.

The solution is to use the @ViewChildren instead of @ViewChild and subscribe the changes subscription that is executed when the component is ready.

For example, if in the parent component ParentComponent you want to access the child component MyComponent.

import { Component, ViewChildren, AfterViewInit, QueryList } from '@angular/core';import { MyComponent } from './mycomponent.component';export class ParentComponent implements AfterViewInit{  //other code emitted for clarity  @ViewChildren(MyComponent) childrenComponent: QueryList<MyComponent>;  public ngAfterViewInit(): void  {    this.childrenComponent.changes.subscribe((comps: QueryList<MyComponent>) =>    {      // Now you can access to the child component    });  }}


To get this to work consistently in my case, I replaced all occurrences of

*ngIf="check"

with

[style.display]="check ? 'block' : 'none'"

Otherwise the ViewChild components that didn't exist when my view first loaded would potentially remain undefined.