Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular material2 Autocomplete binding with complex object list doesn't behave as it should

Autocomplete binding with a complex object doesn't behave as it should. I want to bind the autocomplete to complex object list and assign the selected complex object to another one but when I am doing it it is displaying [object object] in the autocomplete. I have also created the plunker to illustrate the issue

Currently It works only with array list of string. Instead of the binding list with plain string list bind it with the list of complex object.

I am using Angular Material v2.0.0-beta.3 Plunker Link

like image 553
Atul Chaudhary Avatar asked Sep 10 '26 16:09

Atul Chaudhary


1 Answers

It does work as described in the documentation. The key is to use displayWith and (onSelect) to handle object selection, as below.

HTML:

<md-input-container>
  <input type="text" mdInput [formControl]="searchControl" [mdAutocomplete]="usersComp"/>
</md-input-container>

<md-autocomplete #usersComp="mdAutocomplete" [displayWith]="getDisplayFn()">
  <md-option *ngFor="let user of filteredOptions | async" [value]="user" (onSelect)="selected(user)">
    {{user.displayName}}
  </md-option>
</md-autocomplete>

Component:

export class UserSelectComponent implements OnInit {
  @Input() value: any;
  @Output() valueChange = new EventEmitter();

  searchControl: FormControl = new FormControl();
  filteredOptions: BehaviorSubject<any[]> = new BehaviorSubject(undefined);

  constructor(private api: ApiService) {
    this.searchControl.valueChanges.subscribe(data => {
      if (typeof data === 'string' && data.trim() !== '') {
        this.filter(data);
      }
    });
  }

  ngOnInit() {
    this.searchControl.setValue(this.value ? this.value : '');
  }

  private filter(search: string) {
    this.api.get(`search/user/${search}`).subscribe(data => this.filteredOptions.next(data));
  }

  public getDisplayFn() {
     return (val) => this.display(val);
  }

  private display(user): string {
     //access component "this" here
     return user ? user.displayName : user;
  }

  public selected(user) {
    this.value = user;
    //send to parent or do whatever you want to do
    this.valueChange.emit(user);
  }
}
like image 84
PeS Avatar answered Sep 13 '26 17:09

PeS



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!