Search code examples
angulartypescriptangular-materialngmodel

Angular mat-button-toggle rendering does not bind to ngModel


I have been trying to fix a bug where the mat-button-toggle element renders as "selected", even though the ngModel has a false value. And I found something, that at least to me looks strange. Consider a code example:

.html

<mat-button-toggle 
    [(ngModel)]="myVar" 
    (change)="toggle()"
    ngDefaultControl
    name="myVar">
  TOGGLE ME
</mat-button-toggle>

.ts

myVar = false
toggle() {
    // do nothing!
}

I expected:

After you click on the button, it does NOT render as "selected" because myVar still has false value.

What actually happens:

The button renders as "selected" disregarding the actual myVar value.

I have a feeling I miss some core Angular understanding here that makes me unable to understand why doesn't it work like I expect it to. Can you help me understand what is wrong here?


Solution

  • MatButtonToggle does not support angular's two way binding. For Angular two binding to work the component needs to implement ControlValueAccessor which MatButtonToggle does not. Instead you can can listen for the event and manually bind it.

    <mat-button-toggle 
      [checked]="myFlagForButtonToggle" 
      (change)="myFlagForButtonToggle = $event.source.checked">
        Toggle me!
    </mat-button-toggle>