Solution 1 :

Modified here https://stackblitz.com/edit/angular-ivy-v1pjhn?file=src%2Fapp%2Fform%2Fform.component.html

Previous

<select
  id="person"
  class="form-control"
  [ngModel]="current.name"
  #selectRef
  (change)="updateSelect(selectRef.value)"
  >
  <option *ngFor="let data of datas" id="{{data.name}}" [value]="data.name">{{ data.name }}</option>
</select>

Now

<select
  id="person"
  class="form-control"
  [(ngModel)]="current"
  >
  <option *ngFor="let data of datas" [ngValue]="data">{{ data.name }}</option>
</select>

Problem :

Here is a link to my project: https://stackblitz.com/edit/angular-ivy-scycva?file=src/app/form/form.component.ts

I initially have a dropdown, where the user selects one of three users: Jack, Nav, or Pom

After selecting user x, the details of x are displayed below.


I have three datas at the start, and initialize a current object:

  datas: Data[] = [
    new Data(1, "Jack", "[email protected]", "123 Main"),
    new Data(1, "Nav", "[email protected]", "324 Murray"),
    new Data(1, "Pom", "[email protected]", "995 Fortran")
  ];

  current: Data = this.datas[0];

The select dropdown selects current.name as the default value. The options are a list of objects inside datas, and we show the data.name property:

<select
  id="person"
  class="form-control"
  [ngModel]="current.name"
  #selectRef
  (change)="updateSelect(selectRef.value)">
  
  <option *ngFor="let data of datas" id="{{data.name}}" [value]="data.name">{{ data.name }}</option>
</select>

Below are a set of inputs in a form, which should contain data on the person selected:

<form #userForm="ngForm">
    <div class="form-group">
        <label>Name</label>
        <input type="text" class="form-control" name="name" [ngModel]="current.name">
    </div>

    <div class="form-group">
        <label>Email</label>
        <input type="text" class="form-control" name="email" [ngModel]="current.email">
    </div>

</form>

Currently when an update occurs, I change the current object as follows:

  updateSelect(event) {
    this.current = this.datas.filter(d => d.name == event)[0];
  }

I don’t like this way because first of all, names can be the same, and secondly, I feel there must be a better way.

If possible, I want to be able to pass in the data object from the option selected so I can just do this.current = data, but I don’t know if this is possible. I also don’t want to expose anything like an id onto the option field, which the user should not be able to see.

By