How to disable particular option dynamically in Angular Mat-Select

Prashant Pimpale picture Prashant Pimpale · Jul 27, 2018 · Viewed 30.7k times · Source

I have a list with an object has name and id properties:

[
  {
    "name": "open",
    "id": "1"
  },
  {
    "name": "inprogress",
    "id": "2"
  },
  {
    "name": "close",
    "id": "3"
  }
]

And using MatSelect with *ngFor to iterate over an array and bind the current status with select using [(ngModel)].

Expected output:

If the current status is inprogress then disable open option

StackBlitz Example

Answer

G. Tranter picture G. Tranter · Jul 27, 2018

The example doesn't work properly because selected is bound with [value]="topping.id", but the logic uses selected.id which doesn't exist except on startup because you are initializing selected with a topping object.

Also, the logic [disabled]="topping.id < selected.id" is possibly flawed because it also disables inprogress when close is selected - you might want that - I'm not sure - but you only said you wanted to disable open when inprogress is selected.

Either use [value]="topping":

<mat-form-field>
    <mat-select placeholder="Toppings" [(ngModel)]="selected" [formControl]="toppings">
        <mat-option *ngFor="let topping of list" [value]="topping" [disabled]="selected.id === '2' && topping.id === '1'">{{topping.name}}</mat-option>
    </mat-select>
</mat-form-field>

Or change the logic and initialization of selected:

selected: any =  '2';

<mat-form-field>
    <mat-select placeholder="Toppings" [(ngModel)]="selected" [formControl]="toppings">
        <mat-option *ngFor="let topping of list" [value]="topping.id" [disabled]="selected === '2' && topping.id === '1'">{{topping.name}}</mat-option>
    </mat-select>
</mat-form-field>

Update for Angular v6/7 and later

Use [(value)] instead of [(ngModel)]. Support for using the ngModel input property and ngModelChange event with reactive form directives has been deprecated in Angular v6 and is removed in Angular v7.