Reputation: 353
I am getting the following error displayed in screenshot.
When I click the search link, I am displaying the search input, I am using keyup event to get values from input. But getting the error shown in screenshot. I am using angular 6.
component
import { Component, OnInit, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { fromEvent } from 'rxjs';
import { map } from 'rxjs/operators';
@Component({
selector: 'app-temp',
templateUrl: './temp.component.html',
styleUrls: ['./temp.component.css']
})
export class TempComponent implements OnInit, AfterViewInit {
displaySearch = false;
@ViewChild('searchValue') searchValue: ElementRef;
constructor() { }
ngOnInit() {
}
searchFunc() {
if (this.displaySearch === false) {
this.displaySearch = true;
} else if (this.displaySearch === true){
this.displaySearch = false;
}
}
ngAfterViewInit() {
fromEvent(this.searchValue.nativeElement, 'keyup').pipe(
map((event: any) => {
return (event.target).value;
})
).subscribe(res => {
console.log(res);
});
}
}
Html
<div>
<a href="javascript:void(0)" (click)="searchFunc()">Search</a>
</div>
<ng-container *ngIf="displaySearch">
<input type="text" name="searchValue" #searchValue>
</ng-container>
Upvotes: 1
Views: 1777
Reputation: 39432
That's kinda expected.
ngAfterViewInit
would run right after the view gets initialized. And your searchValue
template variable comes in view, only after clicking on the Search link. And in the ngAfterViewInit
method, you're trying to read nativeElement
on something, which at that moment, would be undefined.
Hence the error.
By reading the data from @ViewChild
you're making it unnecessarily difficult for yourself.
How about just listening to the keyup
event on the input
field using the event binding syntax:
<div *ngIf="displaySearch">
<input
type="text"
name="searchValue"
(keyup)="onKeyUp($event.target.value)" />
</div>
And you'll get the value in the onKeyUp
method.
NOTE: The Solution suggested by Vega, is a great solution too. But it won't scale well. Since the ngAfterViewChecked
method gets called on every change detection cycle. So I won't recommend using that.
Here's a Working Sample StackBlitz for your ref.
Upvotes: 1
Reputation: 5265
You cannot use this.searchValue.nativeElement
in ngAfterViewInit()
.
The reason is when TempComponent
is loading searchValue
input is not in the DOM
as displaySearch
is false
at that time. You should use nativeElement
after displaySearch
becomes true
.
change your code as follows.
searchFunc() {
this.displaySearch = true;
setTimeout(() => {
fromEvent(this.searchValue.nativeElement, 'keyup').pipe(
map((event: any) => {
return (event.target).value;
})
).subscribe(res => {
console.log(res);
});
},3000);
}
Upvotes: 2