2

I have a list that I display as checkboxes using angular-material (Angular 7). Below I will add code snippet for .html and .ts files.

Whenever I click on a checkbox it is checked but then immediately un-checked. I entered in debug mode and see that when I click on a checkbox, my isSelected() method gets called 4 times by Angular. When I click on it, it immediately goes to checked state. Then it is still checked the second time that Angular calls it. On the third time, it becomes un-checked (meanwhile isSelected() is still true). I cannot figure out what I did wrong. What I tried is:

  • Switch from isSelected() method to a class property (added the isSelected boolean field on myListItem objects)
  • Added bidirectional binding on top of the previous idea
  • Switch from checked to ngModel

Nothing helped. What else to try, I don't know. Please help me out.

html snippet:

class MyListItem {
  id: number
  name: string
}

// omitted annotations
export class MyComponent implements OnInit, OnDestroy {
  myList: MyListItem[] = [] // omitted initialization

  isSelected(myListItem: MyListItem): boolean {
    return this.myList.includes(myListItem)
  }

  toggle(myListItem: MyListItem): void {
    // omitted the code, I debugged it and it works correctly: 
    // it adds/removes the item to/from the list
  }
}
<mat-list>
  <mat-list-item *ngFor="let myListItem of myList">
    <mat-checkbox flex="100" (click)="toggle(myListItem)" 
                  [checked]="isSelected(myListItem)">
      {{ myListItem.name }}
    </mat-checkbox>
  </mat-list-item>
</mat-list>

4
  • post the code on stackbitz this way no one will be able to help Commented Feb 6, 2019 at 21:11
  • 1
    try to use (change) instead of (click) Commented Feb 6, 2019 at 21:18
  • @quirimmo This also works, thank you, and is, IMO, a neater solution! Commented Feb 6, 2019 at 21:21
  • @ArsenSimonean you are welcome :) just posted as answer too for future readers too Commented Feb 6, 2019 at 21:22

2 Answers 2

1

Use change event not click:

<mat-checkbox flex="100" (change)="toggle(myListItem)" 
                  [checked]="isSelected(myListItem)">
      {{ myListItem.name }}
    </mat-checkbox>
Sign up to request clarification or add additional context in comments.

Comments

1

I am not sure if this will work but you can add an Event parameter to the toggle function.

toggle(myListItem: MyListItem, event: any) { event.preventDefault() }

Then in your html:

(click)="toggle(myListItem, $event)"

Again, Not sure if this will work, but I have found that sometimes these click events will happen automatically, unless the prevent default() function is called

2 Comments

This worked, thank you, but I will use what @quirimmo suggested- to use (change) instead of (click) because it is neater like that.
I understand. Just glad a solution was found

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.