two-way data binding of input checkbox element

Issue

My problem goes like this:

I have this array and variable:

// the options
public items = [{id: 1, main: true}, {id: 2, main: false}, {id: 3, main: false}];

// the selected option
public selectedItem = this.items[0];

and my html looks something like this:

<select id="itemOptions"
        name="itemOptions"
        [(ngModel)]="selectedItem">
  <option *ngFor="let item of items" [ngValue]="item">{{item.id}}</option>
</select>

<input id="mainItem" 
       name="mainItem" 
       type="checkbox"
       [(ngModel)]="selectedItem.main"
       (ngModelChange)="setMain()" >

and the setMain function looks like this:

setMain() {
  for(let item of this.items){
    //set all items` main to false if they are not the selected item
    if(this.selectedItem.id != item.id){
      item.main = false;
    }
    //if it is the selected item, set it as the main item
    else if(this.selectedItem.id == item.id){
      item.main = true;
    }
  }
}

the point here is there must be a main item at all times.
but when I select the main item and uncheck it the function works great and the main stays true, but the checkbox is still unchecked.

I’ve read this post and some more but did not found something that look like my case, nor clues for an answer.
As I understand the two-way data binding, when I clicked the checkbox it changed the value of my selectedItem.main to false. but then the setMain is called and sets it back to true. Why the checkbox doesn’t become checked back?

Any way of achieving this would be great :).

note: I don’t want to set the checkbox checked to true manually. I want to understand why the two-way data binding doesn’t handle this case.

Solution

Solution to your situation

is put all the code of setMain within setTimeout :

setMain() {
    setTimeout(() => {
        for(let item of this.items){
            //set all items` main to false if they are not the selected item
            if(this.selectedItem.id != item.id){
                item.main = false;
            }
            //if it is the selected item, set it as the main item
            else if(this.selectedItem.id == item.id){
                item.main = true;
            }
        }
    })
}

WORKING DEMO

For more detail please check : Angular 2 – Checkbox not kept in sync

Answered By – Vivek Doshi

Answer Checked By – Pedro (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.