Angular mat-checkbox indeterminate not behaving as expected

I’m using Angular 7 and Angular Material 7.3.7, and I’m trying to create an unordered list of mat-checkbox. I am experiencing inconsistent behavior, where the indeterminate is not always showing when it should. Here is my code:

HTML:

<ul>
  <li *ngFor="let persona of personas">
    <mat-checkbox [checked]="persona.checked" [indeterminate]="persona.indeterminate">
      {{ labels[persona.name] }}
    </mat-checkbox>
  </li>
</ul>

TS:

// Called by event listener. Updates the data displayed by checkboxes
updateDataCallback = () => {
  // does some logic
  // updates personas object, for example:
  this.personas = [
    {name: 'persona1', checked: false, indeterminate: false},
    {name: 'persona2', checked: false, indeterminate: true},
    {name: 'persona3', checked: false, indeterminate: false},
    {name: 'persona4', checked: false, indeterminate: false},
  ]
}

The specific issue I’ve noticed is that when I move from this state checked: true, indeterminate: false to this state checked: false, indeterminate: true it does not change – the checkbox stays checked and does not represent the indeterminate state. I haven’t found any other issues but it wouldn’t surprise me if there are other similar issues.

Is there some other way I should be handling the checked and indeterminate logic? This seems to work okay most of the time, but with some of the corner cases I need to find a better solution. Thanks!

Answer

In the documentation of Angular Material, it is stated that:

check-indeterminate: Default behavior of mat-checkbox. Always set indeterminate to false when user click on the mat-checkbox. This matches the behavior of native

So, it seems after toggling on the checkbox, the indeterminate state becomes false and then we cannot see the state again unless we explicitly set it to false again. There is an example in the documentation which will provide you an idea of how to make use of indeterminate state. Refer the link (stackblitz) to their example.