Mat-checkbox checked not changing checkbox state

26,215

Solution 1

so I have an answer for you. don't need to use a radio button as your designer hate it just use

<mat-checkbox [checked]="selectedLanguage === 'en'" (change)="switchLanguage('en')">English</mat-checkbox>
<mat-checkbox [checked]="selectedLanguage === 'fr'" (change)="switchLanguage('fr')">French</mat-checkbox>
<mat-checkbox [checked]="selectedLanguage ==='de'" (change)="switchLanguage('de')">German</mat-checkbox>

check for type and value too using selectedLanguage === 'en'

also, use (change)="switchLanguage('de') instead of click

working here or check this

Solution 2

You should use (change) instead of (click). Your template should be changed to this:

<mat-checkbox [checked]="selectedLanguage === 'en'" (change)="switchLanguage($event, 'en')">English</mat-checkbox>
<mat-checkbox [checked]="selectedLanguage === 'fr'" (change)="switchLanguage($event, 'fr')">French</mat-checkbox>
<mat-checkbox [checked]="selectedLanguage === 'de'" (change)="switchLanguage($event, 'de')">German</mat-checkbox>

... and your function will look like this:

public switchLanguage(event: MatCheckboxChange, lang: string) {
    if(event.checked && this.selectedLanguage!== lang){
        this.selectedLanguage = lang;
        // this.translateService.use(lang); // changing ngx-translate language
        console.log('Switched to ' + lang);
    }
}

Remember to import MatCheckboxChange

import { MatCheckboxChange} from '@angular/material';`

Link to Demo.


You should use radio buttons for this behavior. Checkbox is not the correct way to go when you only have to allow a single option selection.

<mat-radio-group [value]="selectedLanguage">
  <mat-radio-button value="en" (click)="switchLanguage('en')">English</mat-radio-button>
  <mat-radio-button value="fr" (click)="switchLanguage('fr')">French</mat-radio-button>
  <mat-radio-button value="de" (click)="switchLanguage('de')">German</mat-radio-button>
</mat-radio-group>

Here is a StackBlitz Demo.

Solution 3

Alternatively to other answers you can choose not to use a separate function to handle the change event, but instead assign a value like this: (change)="myBooleanVar = $event.source.checked" This example does not work in OP's case, but might be useful to other people who use checkboxes to assign yes/no values.

Solution 4

(click) is a DOM event, whereas (change) is generated from the Angular framework.

Click will have a generic DOM event object, and Change the MatCheckboxChange object.

Click fires first.

Share:
26,215
Wis
Author by

Wis

Angular, Spring and Java EE programmer with former PHP experience having M.Sc. in computer science since January 2008. Currently working for a Swiss software development company in the french part of the country. Computer geek, webmaster, gamer and technology enthusiast.

Updated on July 11, 2021

Comments

  • Wis
    Wis almost 3 years

    I'm implementing a language switch component which display checkboxes, one for each language of the app (translations with @ngx-translate).

    When clicking one of the checkbox, app language is correctly switched but the clicked mat-checkbox is still unchecked.

    Template :

    <mat-checkbox [checked]="selectedLanguage == 'en'" (click)="switchLanguage('en')">English</mat-checkbox>
    <mat-checkbox [checked]="selectedLanguage == 'fr'" (click)="switchLanguage('fr')">French</mat-checkbox>
    <mat-checkbox [checked]="selectedLanguage == 'de'" (click)="switchLanguage('de')">German</mat-checkbox>
    

    Component :

    export class CheckboxOverviewExample {
      public selectedLanguage: string;
    
      constructor(){
        this.selectedLanguage = 'fr';
      }
    
      public switchLanguage(lang: string) {
        this.selectedLanguage = lang;
        // this.translateService.use(lang); // changing ngx-translate language
        console.log('Switched to ' + lang);
      }
    }
    

    The [checked] binding is working when you route to the component. The mat-checkbox for french is indeed checked when landing to the component (default value). Now when I click on german or english, the language does switch, the french checkbox does correctly uncheck, however the clicked checkbox does not check.

    I'm missing something, might be a small detail, but I do not understand why the german / english does not check while the french does correctly uncheck.

    Have a look at this simple stackblitz code to reproduce my case.

  • Wis
    Wis about 6 years
    I understand your point, but you are not answering to the question, which is not if there exist another component I can/should use. I have to use a checkbox because our web designer did use it on his app mock-up. It's a visual choice (might be our designer hates radios).
  • Wis
    Wis about 6 years
    Can you explain the difference between (click) and (change) ? It's working but I'd like to understand why one is working and not the other. Both should trigger a change detection cycle to my knowledge.
  • Wis
    Wis about 6 years
    Can you explain the difference between (click) and (change) ? It's working but I'd like to understand why one is working and not the other. Both should trigger a change detection cycle to my knowledge.
  • Hrishikesh Kale
    Hrishikesh Kale about 6 years
    as you can also check, in given stackblitz using change method is fired when checkbox losses focus and click method on click so if you used clicked instead of changed you need to click the element twice to check and in some browser, it will be difficult for a user so it's better to use change.
  • Hrishikesh Kale
    Hrishikesh Kale about 6 years
    in my solution it will also work on click but you need to double-click the checkbox to get click
  • Admin
    Admin almost 3 years
    For me, changing (click) with (change) did the trick, thank you