I have an element in my HTML like this (inspiration from this blog). While the user types, I'm showing successive filtrations in a list to pick from. Once the user clicks on that component, I want to update the value typed in the search box below and replace it with the full name available in the clicked item.
<input #userSelector (keyup)="onKeyUpUser($event)">
In order to communicate easily, I have set up a view child as shown below. Then, in the handler of the click, I set the value picked.
@ViewChild("userSelector") userSelector: ElementRef;
...
onClickUser(user: User) {
this.userSelector.nativeElement.value = user.name;
...
}
This works as expected. Now, I wanted to be clever and realized that the view child is not only a general ElementRef but, in fact, HTMLInputElement, so I replaced the code like this.
@ViewChild("userSelector") userSelector: HTMLInputElement;
...
onClickUser(user: User) {
this.userSelector.value = user.name;
...
}
To my surprise, it doesn't update the contents visible on the screen. In the console, I can see that the field value has appeared and has the value I assigned. But it won't show. It's the same element, so I'm confused why this happens.
What's the reason this occurs and (how) can I use the more specific type of the view child (hence allowing to avoid the detour through nativeElement to get to the value field?
It is indeed correct to type the property decorated with
ElementRef, but it is just not enough: just add the generic type toElementRef.The
ViewChilddecorator give you access to a typedElementRef(in this case ofHTMLInputElement=>ElementRef<HTMLInputElement>), not to anHTMLInputElementone!If you want to observe a child component, you will directly get the component instance (so, no need to type the property to
ElementRef<MyChildComponent>>). In that case you can just do the following: