angular / components

Component infrastructure and Material Design components for Angular
https://material.angular.io
MIT License
24.14k stars 6.67k forks source link

bug(MatAutocomplete): setValue on FormControl does not update AutoComplete Input #29063

Closed ChazUK closed 1 week ago

ChazUK commented 2 weeks ago

Is this a regression?

The previous version in which this bug was not present was

No response

Description

When using a custom input field with a FormControl, I am unable to dynamically set the value of the input element via setValue().

https://stackblitz.com/edit/vavcrk

Reproduction

https://stackblitz.com/edit/vavcrk

Expected Behavior

Using setValue() on the FormControl should update the value of the input element.

Actual Behavior

Input element value continues to be empty

Environment

ChazUK commented 2 weeks ago

Just to clarify I want to update the query string that goes into the matInput field dynamically in code.

lsamboretrorabbit commented 1 week ago

Since you are working with an Autocomplete that expects a User object or a string that represents the user's name.

By updating your test function to something similar to below. You will then be able to dynamically set your FormControl

test() {
    this.myControl.setValue({ name: 'HELLO' });
  }
ChazUK commented 1 week ago

@lsamboretrorabbit that's the bit where maybe I'm getting a bit confused. I don't want to update the selected value, I want to update the query value that will be used to derive the autocomplete options. And from what I can tell there isn't a way to be able to do that.

Also the FormControl typing is set to string | User which would make me think I can update it with a string and it still search.

crisbeto commented 1 week ago

The reason your example doesn't work is because the display function expects only a User, but your value is User | string. It works if you change it to this:

displayFn(user: User | string): string {
    if (typeof user === 'string') {
      return user;
    }

    return user && user.name ? user.name : '';
  }