question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Feature: Possibility to make the [displayWith] of Autocomplete more flexible

See original GitHub issue

Bug, feature request, or proposal:

Feature Request.

What is the expected behavior?

I expect [displayWith] to give me back the whole object so I can treat what property I can return to display (doesn’t it make sense)?

What is the current behavior?

Actually [displayWith] is too limited.

Ex:

I have the following variable that gets the content from API:

this.myObs = this.<service>.<fetch>();

That’s the content coming from back-end:

[
  { id: 1, name: 'anyName' },
  { id: 2, name: 'xxx' }
];

In template I have:

<md-input-container>
  <input mdInput placeholder="State" (keyup)="onKeyUp($event)" [mdAutocomplete]="auto" [formControl]="objCtrl">
</md-input-container>

<md-autocomplete #auto="mdAutocomplete" [displayWith]="displayFn.bind(this)">
  <md-option *ngFor="let obj of myObs | async" [value]="obj.id">
    {{ obj.name }}
  </md-option>
</md-autocomplete>

Since, I’m binding the md-option to id, [displayWith] just gives me the value of id while I was expecting at least the full object so I can return the name, for example.

Workarounds:

1- Subscribe to the observables and store in arrays.

Problem 1: You’ll have to loop through the array everytime that an option is selected to return the desired property.

Problem 2: Imagine that I have more than 10 autocomplete (my case), I’ll have to create 10 variables and subscribe them all while I could simply use the async pipe (as I’m doing) and, consequently I wouldn’t need to subscribe in nothing.

2 - Bind the full object to <md-option>, so [displayWith] will give me back the whole object.

Problem: If your API expects a single property (in my case back-end expects only the id), before submits the form, you’ll have to change the whole content of form that was stored as object to id.

What are the steps to reproduce?

Providing a Plunker (or similar) is the best way to get the team to see your issue. Plunker template: https://goo.gl/DlHd6U

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

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

Material 2.0.0-beta.6

Is there anything else we should know?

The workarounds can be used? Ofc they can, however it’d be really better if Material2 could provide a better solution for this.

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:35
  • Comments:28 (4 by maintainers)

github_iconTop GitHub Comments

33reactions
nayfincommented, May 28, 2019

I agree that it this issue needs some love. I’m not sure why it doesn’t just behave like the mat-select does and default to display the value that’s in the selected panel. I’ve been able to use function composition to get the desired behavior here by passing the options into the displayWith function and finding the selected option by id ( which is the selected options [value]), then returning its name.

here’s the important stuff in the component.ts

options: User[] = [
  {name: 'Mary', id: 1},
  {name: 'Shelley', id: 2},
  {name: 'Igor', id: 3}
];
// we expect the options to be passed in from the template
// then we return a callback function that will expect an id which is passed in by the autocomplete event logic
displayFn(options: User[]): (id: number) => string {
  return (id: number) => { 
    const correspondingOption = Array.isArray(options) ? options.find(option => option.id === id) : null;
    return correspondingOption ? correspondingOption.name : '';
  }
}

and the important piece in the template

<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn(options)">
  <mat-option *ngFor="let option of filteredOptions | async" [value]="option.id">
    {{option.name}}
  </mat-option>
</mat-autocomplete>

Additionally, if you throw a console.log in the function, you’ll see that this is running a lot. So, a few of these on a form could impact performance.

6reactions
mrmokwacommented, Dec 28, 2018

I think this request is really important for us developers and should not be left in ostracism. The solutions above work, but feels like jerry-rig.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to display using [displayWith] in AutoComplete Material2
I know I have to use displayWith , however it isn't working as I'm expecting. The function called as [displayWith]="displayFn.bind(this)"> just ...
Read more >
Angular Material as a base for reusable components - LinkedIn
First lets create our new auto complete component based on Angular Material, in the meantime we can also increase its functionality:.
Read more >
mat-autocomplete displayWith async (how to return from ...
The custom control uses angular material's mat-autocomplete. ... I am trying to use the [displayWith] attribute in order to get to the ...
Read more >
Feature Updates - isee systems
There is also a new action to export the variables in a Table making it easier to keep exports up to date with...
Read more >
Liferay Portal 7.3 CE GA2 Release
Ability to have autocomplete in the fragment editor for variables, ... More flexible configuration of the number of items display with RSS Publisher....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found