Cannot read property 'native-element' of undefined Angular 8

Stack Overflow picture Stack Overflow · Jul 2, 2019 · Viewed 19.3k times · Source

after my angular application versions upgrade from angular 7 to angular 8 i run into a complication problem with rows like this

export class followupComponent implements OnInit {
    @ViewChild('message') messageElement: ElementRef;

    constructor(){}
    ...
}

I read that the new definition required static parameter and change the code

@ViewChild('message', { static: true })) messageElement: ElementRef;

and I thought that the problem had resolved.

But no, i accept run time error:

cannot read property 'nativeElement' of undefined

related to this code

HTML:

<div class="message">
    <div class="action-buttons">
        <img src="{{imgPath + '_Edit_Hover.png'}}" (click)="OnEdit(Followup)">
    </div>
    <textarea matInput #message [ngModel]="Followup.Message"></textarea>
</div>

TS:

OnEdit(followup: Followup) {
    setTimeout(() => this.messageElement.nativeElement.focus());
}

What is the correct definition of ElementRef in angular 8,

or - How to resolve this problem?

Answer

ysf picture ysf · Jul 2, 2019

<textarea matInput #message [ngModel]="Followup.Message"></textarea> this piece of code probably needs some logic to get displayed (such as *ngIf or *ngFor on parent nodes, or some asynchronous code) which means that one changedetection cycle is required for it to get displayed.

According to Angular 8 docs

static - whether or not to resolve query results before change detection runs (i.e. return static results only). If this option is not provided, the compiler will fall back to its default behavior, which is to use query results to determine the timing of query resolution. If any query results are inside a nested view (e.g. *ngIf), the query will be resolved after change detection runs. Otherwise, it will be resolved before change detection runs.

so you should set static to false

@ViewChild('message', { static: false })) messageElement: ElementRef;

here is a simple demo https://stackblitz.com/edit/angular-qgwhcv

in the demo above, input box gets displayed after 3 seconds. if you set static:false and click edit after input gets displayed it successfully focuses the input. but if you change static:true and click edit after input gets displayed, you will see error in the console.