0

I have Angular 8 mat-autocomplete with [displayWith]="getDropdownView" where

getDropdownView(option) {
    console.log("getDropdownView(): option:", option);
    return "abc";  // FOR TEST
    // return option.value;
}

For one page this works ok, but for another one this shows [Object Object]. There is such HTML code:

<input matInput placeholder="Начните вводить..." [matAutocomplete]="auto" [id]="field.field"
    [value]="getDropdownValue(field.field)"
    (input)="loadDropdownData($event.target.value, field.field)">

<mat-autocomplete #auto="matAutocomplete" autoActiveFirstOption
    (optionSelected)="onDropdownSelected($event.option.value, field.field)"
    [displayWith]="getDropdownView">

    <mat-option *ngIf="dropdownIsLoading[field.field]" class="is-loading">
        <mat-spinner diameter="50"></mat-spinner>
    </mat-option>

    <mat-option *ngFor="let option of dropdownData[field.field]" [value]="option" style="width: 300px">
       <span>{{ option.value }}</span>
       <small> | ID: {{option.id}}</small>
    </mat-option>

</mat-autocomplete>

Also *.ts has this method:

getDropdownValue(field_name) {
    let id = this.model.data[field_name];
    for (let i in this.dropdownData[field_name]) {
      let option = this.dropdownData[field_name][i];
      if (option.id === id) {
        console.log("getDropdownValue(): option:", option);
        return option;
      }
    }
    console.log("getDropdownValue(): option: null");
    return null;
  }

Execution log when I change selected items via dropdown menu (without text input):

  1. getDropdownValue() for input's [value] gets called multiple times with correct old item (to set composite object as autocomplete's chosen value);
  2. getDropdownView() for mat-autocomplete's [displayWith] gets called with correct new item (to get shown value from new composite object);
  3. onDropdownSelected() for mat-autocomplete's (optionSelected) gets called with correct new item (to inform *.ts that option has been chosen);
  4. getDropdownValue() for input's [value] gets called multiple times again with correct new item.

How can I get right displayWith instead of [Object Object]?

Evgeny Nozdrev
  • 1,530
  • 12
  • 15

1 Answers1

1

Try removing [value]="getDropdownValue(field.field)" from your <input>.

Take an array field and bind that to your input as a model, not as a value. then on every new select, add the new value to the existing array.

To handle the pre-population: get the values in the constructor of your component and assign all of them to the array field.

Above solution is when you are not using formControls, if you use formControls, you can assign the values to the formControl field, that we just assigned to the array.

Sandeep Kumar
  • 2,397
  • 5
  • 30
  • 37
  • This fixed the problem, but: 1. How does this work? 2. Why on another page dropdown works with `[value]`? – Evgeny Nozdrev Dec 10 '19 at 07:58
  • 1
    `[value]` is used to bind a variable to your input field, which is not required when we are using auto-complete as auto-complete takes care of setting the selected value to the input thru `[matAutocomplete]="auto"`. I'm not sure how it's working on the other page, probably the binding there is not return any object, hence the auto-complete value is showing properly. – Sandeep Kumar Dec 10 '19 at 08:02
  • There is another problem: without `[value]` autocomplete's value can't be preselected when page opened. – Evgeny Nozdrev Dec 10 '19 at 08:11
  • can you share `getDropdownValue(field.field)`? – Sandeep Kumar Dec 10 '19 at 08:20
  • change your return statement to: `return option.value;` and keep `[value]` – Sandeep Kumar Dec 10 '19 at 08:32
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/203962/discussion-between-evgeny-nozdrev-and-sandeep-kumar). – Evgeny Nozdrev Dec 10 '19 at 08:39