Search code examples
htmlangulartypescripthtml-selectangular-reactive-forms

How to dynamically set default value in `select` control


I am subscribing to the HTTP server for the data to receive after which my select control gets loaded with the data by Angular framework. My goal is to set the default value. My default value consists of three values from the object I have received from the server separated by "/", so the HTML code looks like this:

<label>{{ functionStr }}</label>
<select #element formControlName="selectedUser" class="form-select" (change)="changeClient($event)">
    <option *ngFor="let account of accountsAvailable4Function">{{ account.firstName }}/{{ account.lastName }}/{{ account.email }}
    </option>
</select>

I have used the default value when initializing FormGroup:

var selected = this.accountsAvailable4Function[1].firstName+"/"+this.accountsAvailable4Function[1].lastName+"/"+this.accountsAvailable4Function[1].email
this.form = this.formBuilder.group({
      scheduledDate: ['', Validators.required],
      selectedUser: [selected, [Validators.required]],
    });

This throws an exception because my accountsAvailable4Function array is not initialized yet.

I tried to set it using the FormGroup control as below. This also does not work because I suspect that the control is not loaded yet:

var selected = this.accountsAvailable4Function[1].firstName+"/"+this.accountsAvailable4Function[1].lastName+"/"+this.accountsAvailable4Function[1].email
this.f['selectedUser'].setValue(selected);
      

Is there some event that I could listen to, to notify me when select control is loaded?

Appended: Loading accountsAvailable4Function array:

this.accountService.getAll()
      .pipe(first())
      .subscribe({
        next: (accounts: Account[]) => {
          accounts.forEach(account => {
            account.userFunctions.forEach(userFunc => {
              if(userFunc.userFunction == this.functionStr) {
                this.accountsAvailable4Function.push(account);
              }
            });
          });
          
          /* HTML select control selects by default first element - verify it*/
          this.selectedAccount = this.accountsAvailable4Function[0];
          this.dataSource = new MatTableDataSource(this.accountsSelected4Function);
          this.dataSource.paginator = this.paginator;

        },
        complete: () => {
          this.accountsLoaded = true;
          var selected = this.accountsAvailable4Function[1].firstName+"/"+this.accountsAvailable4Function[1].lastName+"/"+this.accountsAvailable4Function[1].email
          this.f['selectedUser'].setValue(selected);
        },
        error: error => {
          this.alertService.error(error);
          this.accountsLoaded = true;
        }
      });         

Solution

  • From your current code, you are missing the value attribute for the <option> elements. This results that the <option> elements' value as the empty string as default. Thus you see the <select> element is not bonded with the default value.

    You need to set the value attribute as mentioned to the <option> as template expression [].

    <select #element formControlName="selectedUser" class="form-select" (change)="changeClient($event)">
      <option *ngFor="let account of accountsAvailable4Function" 
        [value]="account.firstName + '/' + account.lastName + '/' + account.email">
          {{ account.firstName }}/{{ account.lastName }}/{{ account.email }}
      </option>
    </select>