angularmat-autocomplete

mat-autocomplete selected mat-option pass multiple values from selectedItem


I have a mat-autocomplete that loads table data that is in JSON format and currently maps a single JSON value as the selected "value" when the user selects an item from the autocomplete.

In addition to this value, I also need to pass some other values from this selected item's JSON node, as these values are being written to a database. So I need 3 values from this selected object, not just one.

But I'm not sure how to access those additional JSON properties from the existing interface or if I need to modify the interface to allow those values to be passed as well.

For example, the table data that populates the autocomplete is below and we are currently using the "codeFileType" as the "value" passed when a user selects an item from the autocomplete table:

"table-lookups": [
{
  "codeFileType": "NEW_CODE_FILE_TYPE_A",
  "datasource": "A",
  "myAutoCompleteHook": "autocompleLookupTest1",
  "myAutoCompleteParams": [
    {
      "name": "_endpoint",
      "value": "MyCodeFile"
    },
    {
      "name": "_labelKey",
      "value": "code"
    },
    {
      "name": "_valueKey",
      "value": "description"
    }
  ]
},
{
  "codeFileType": "NEW_CODE_FILE_TYPE_B",
  "datasource": "B",
  "myAutoCompleteHook": "autocompleLookupTest2",
  "myAutoCompleteParams": [
    {
      "name": "_endpoint",
      "value": "MyCodeFile"
    },
    {
      "name": "_labelKey",
      "value": "code"
    },
    {
      "name": "_valueKey",
      "value": "description"
    }
  ]
},
{
  "codeFileType": "NEW_CODE_FILE_TYPE_C",
  "datasource": "C",
  "myAutoCompleteHook": "autocompleLookupTest3",
  "myAutoCompleteParams": [
    {
      "name": "_endpoint",
      "value": "MyCodeFile"
    },
    {
      "name": "_labelKey",
      "value": "code"
    },
    {
      "name": "_valueKey",
      "value": "description"
    }
  ]
}

],

So, from above JSON, we are mapping the codeFileType as the "value" of the select. I also need to access the selected item's "myAutoCompleteHook" and "myAutoCompleteParams" values as well and pass those along with codeFileType as separate data points.

Here is the HTML format of the mat-option element where we are binding the [value] to the valueKey:

<mat-option
 *ngFor="let values of filteredResults$ | async; trackBy: trackByFn; index as i"
 [value]="values[tableConfig?.valueKey]"
 [innerHtml]="buildLabelFromValuesChecked(values, isOptionSelected(values[tableConfig?.valueKey]))">
</mat-option>

Solution

  • You can just pass the index of the selected item, and access the full object from the array using the index number. Easiest thing ever.

    <mat-option
     *ngFor="let values of filteredResults$ | async; trackBy: trackByFn; index as i"
     [value]="i"
     [innerHtml]="buildLabelFromValuesChecked(values, isOptionSelected(values[tableConfig?.valueKey]))">
    </mat-option>
    

    component.ts:

    // function that is assigned to mat-selected
    someFunction(index: number) {
      this.selectedItem = this.table-lookups[index]
    }
    

    I also see you are running the *ngFor on filteredResults$. If filteredResults$ is not same as table-lookups, then you can bind value to codeFileType and use findIndex or filter.

    [value]="codeFileType"
    

    component.ts:

    // function that is assigned to mat-selected
    someFunction(value: string) {
    
    // filter
      this.selectedItem = this.table-lookups.filter((item) => item.codeFileType === value)[0] // since filter returns an array
    }
    
    // or findIndex
      const itemIndex = this.table-lookups.findIndex((item) => item.codeFileType === value) // since filter returns an array
      this.selectedItem = this.table-lookups[itemIndex];
    }
    

    Then you can use this.selectedItem.myAutoCompleteHook and this.selectedItem.myAutoCompleteParams to access those props.