0
votes

What is the optimal way of setting the Default Value for a Angular Material Select dropdown? The mat select is calling an API which populates the dropdown list. Then its preselecting the value to defaultAddressFormat variable. Its being done in the subscribe function.

Curious if there is more optimal way of doing this, this.addressService.getAddressFormatAll() is an observable

After presetting value, user should be able to select different selection if needed.

If the default is set before API fully loads, sometimes it may not render, so being called in subscribe method.

this.addressService.getAddressFormatAll().subscribe(res => {
    this.addressFormatList = res.body;
    if (this.addressFormatList.length > 1) {
      this.addressHeaderForm.patchValue({ addressFormat: this.defaultAddressFormat });
    }
});


<mat-form-field>
     <mat-label>Address Format</mat-label>
     <mat-select
          formControlName = "addressFormat"
          [compareWith]="compareAddressFormatDataObjects"
          placeholder ="Select"
          (selectionChange)="addressFormatChangeEvent($event)" required >
          <mat-option (click)="addressHeaderForm.controls.addressFormat.reset()">Select</mat-option>
          <mat-option
               *ngFor="let addressFormatItem of addressFormatList"
               [value]="addressFormatItem"
           >
           {{addressFormatItem.addressFormatDescription}}
           </mat-option>
      </mat-select>
  </mat-form-field> 

Other resources:

Set default option in mat-select

Angular Material: mat-select not selecting default

1

1 Answers

0
votes

This is already one of the optimal ways of doing so. As you have known, HTTP requests are asynchronous, thus doing something like:

this.addressService.getAddressFormatAll().subscribe()
this.addressHeaderForm.patchValue({ addressFormat: this.defaultAddressFormat });

Won't work, as the patchValue method will be called before getAddressFormatAll has been subscribed and returned.

Therefore, your code is valid, and I don't think there is a need to change anything within it.

Of course, there areyou could choose to handle it as a side effect through RxJS pipeline, but doing so would bring no additional benefit, unless you are working with other operations, such as additional asynchronous methods to be called.

this.addressService.getAddressFormatAll()
  pipe(
    tap((res) => {
      this.addressFormatList = res.body;
      if (this.addressFormatList.length > 1) {
        this.addressHeaderForm.patchValue({ addressFormat: this.defaultAddressFormat });
      }
    }),
  ).subscribe();

Alternatively, you can make use of the async pipe. One benefit of doing so, is that you do not need to manually unsubscribe on your component.

this.addressFormatList = this.addressService.getAddressFormatAll()

And on your component.html,

<mat-option
  *ngFor="let addressFormatItem of addressFormatList | async"
  [value]="addressFormatItem"
>