components icon indicating copy to clipboard operation
components copied to clipboard

Autocomplete should always handle display value and model separately

Open gempain opened this issue 6 years ago • 3 comments

Bug, feature request, or proposal:

Feature request / proposal

What is the expected behavior?

Assuming the following:

TS

options = [{name: 'One'}, {name: 'Two'}];
text: string;

HTML

<input type="text" matInput [(ngModel)]="text" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
    <mat-option *ngFor="let option of options" [value]="option">
      {{option.name}}
    </mat-option>
</mat-autocomplete>

I expect text to be of type string at any time. When selecting an option from the dropdown, I do not expect that value to be assigned to the input value. MatAutocomplete should provide a separate ngModel to be bound to. Sure, the selected option should be displayed in the input, but using a string. This is possible via the [displayWith] input of <mat-autocomplete>, but should not be an "opt-in" feature, it should be required.

What is the current behavior?

When you select an option, text is now of type {name: string}, because Angular Material autocomplete assigns the selected value to it.

What are the steps to reproduce?

What is the use-case or motivation for changing an existing behavior?

When you fetch search results from a backend, you're usually subscribing to valueChanges (if using FormControl) or ngModelChange (if using ngModel). You would expect such subscriptions to stream values of the same type at runtime.

In the docs, you have worked around this problem by doing the following:

map(value => typeof value === 'string' ? value : value.name),

Which works fine, but is not intuitive, and semantically awkward. The docs aren't clear about this specific semantic inconsistency which may cause users (like me) to waste some time trying to understand why typing is not preserved until realizing it's not a bug, but an intended behavior.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Angular 7

Is there anything else we should know?

gempain avatar Nov 10 '18 22:11 gempain

Just a heads up that we kicked off a community voting process for your feature request. There are 20 days until the voting process ends.

Find more details about Angular's feature request process in our documentation.

angular-robot[bot] avatar Feb 01 '22 18:02 angular-robot[bot]

Thank you for submitting your feature request! Looks like during the polling process it didn't collect a sufficient number of votes to move to the next stage.

We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular's scope, we'd encourage you to collaborate with the community on publishing it as an open source package.

You can find more details about the feature request process in our documentation.

angular-robot[bot] avatar Feb 22 '22 15:02 angular-robot[bot]

Is there any update on this? I recently implemented a mat-autocomplete in a component with reactive forms and it just felt messy. It works but it doesn't feel like an optimal implementation, it would be really nice if an OnSearch event was fired or have a seperate form control that could be bound to. This way I wouldn't have to expand my FormControl<T> type to include string and type check typeOf x === 'string' every time when reading values. Also if the result value type actually needed to be a string it is impossible to differentiate between a search value and an actual result.

to-ros avatar Jul 27 '22 05:07 to-ros

exact ! Since FormControl are strict-typed objects, this issue becomes more important to consider

morgan-germain avatar Oct 19 '22 09:10 morgan-germain