0

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 Answers1

0

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"
>
wentjun
  • 40,384
  • 10
  • 95
  • 107
  • ok, thanks, it felt like I was placing too much in the subscribe method,also I heard it best practice to use | async pipe when calling the data list, just wanted to be sure, thanks –  Feb 17 '20 at 01:25
  • Ahh, you can use async pipe too. The benefit is that, you don't need to unsubscribe – wentjun Feb 17 '20 at 01:28