0

This might be a stupid question with a very simple answer, but after a week of coding I feel fried and can't figure it out.

How can I bind to the Id of a selection, but display the string representation of the value? I.e., I have a drop-down that display the names of Customers, but I want to save the Id for DB purposes.

My selection item has two properties: customer.Display (Name), and customer.Id.

How can I do the binding to save my Id to [(ngModel)]="loadDataService.selectedLoad.CustomerId, but display my Display in the drop-down (it already displays the Display, so that is covered):

<mat-form-field>
    <input type="text" placeholder="Customer Search" id="CustomerId" name="CustomerId" aria-label="Number" matInput [formControl]="myCustomerSearchControl"
      [matAutocomplete]="auto" [(ngModel)]="loadDataService.selectedLoad.CustomerId" (keyup)="onCustomerSearch($event)">
    <mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
      <mat-option *ngFor="let customer of customerArray" [value]="customer.Display">
        {{ customer.Display }}
      </mat-option>
    </mat-autocomplete>
</mat-form-field>
onmyway
  • 1,435
  • 3
  • 29
  • 53
  • 1
    `[value]="customer.Display"` should be `[value]="customer.Id"` ... Unless that's something else, because that really seems too easy –  Mar 09 '18 at 12:46
  • Hey trichetriche, jip, too easy ;). When I bind `[value]="customer.Id"`, it displays that value (Id) as the selected value in the input field. I.e., it show a GUID and not the user-friendly name. I am binding to my data service `[(ngModel)]="loadDataService.selectedLoad.CustomerId"` with the selected value. But with my setup, it is the `customer.Display` and not the `customer.Id`. *pulling my hair out* :D – onmyway Mar 12 '18 at 05:47
  • Oh, I see your issue. Let me get to work and I'll handle that for you. –  Mar 12 '18 at 06:40
  • Thanks! i would really appreciate it! :) – onmyway Mar 12 '18 at 07:18

1 Answers1

1

When you use the autocomplete, you have a optionSelected event. You need to use that to find your selected option.

<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" (optionSelected)="setServiceId($event)">
  ...
</mat-autocomplete>

Then, in your component, you must implement that function :

setServiceId(dislay: string) {
  const id = this.customerArray.find(c => d.Display === display).id;
  this.loadDataService.selectedLoad.CustomerId = id;
}

This way of doing assumes you have unique customer displays. If not, you will need to use this function, with the previous HTML + this HTML :

setServiceId(customer: any) {
  this.loadDataService.selectedLoad.CustomerId = customer.id;
}
  • Thank you for the solutions. i like where you are going with this, and I think it is close. I tried both methods, but the first seems to be the one. However, I had to make some changes, as I got an error: Cannot read property id of undefined. So modified the one line to the following: `const customer = this.customerArray.find(c => c.Display === display.option.value);` But this also updates my selected drop-down value to equal the Id. I.e., it changes the display from customer name to customer id. – onmyway Mar 12 '18 at 08:21
  • That's because you bind your service value directly to your input with `[(ngModel)]="loadDataService.selectedLoad.CustomerId"`. You should create a variable in your component and use the `onSelected` output, like I showed you, to set the value of your service. –  Mar 12 '18 at 08:23
  • Jip, figured it out. I removed my [()] binding to make it work. Tx! – onmyway Mar 12 '18 at 08:26