1

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.

Dzak
  • 412
  • 4
  • 17

2 Answers2

2

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

Vivek Doshi
  • 56,649
  • 12
  • 110
  • 122
0

I have tried as below please check is it that you required?

<input id="mainItem" 
name="mainItem" 
type="checkbox"
[(ngModel)]="selectedItem.main"
(click)="setMain($event.target.value)" >

setMain(value) {  
    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 = !value;
        }
    }
}
  • hmm tried to use your code but its acted the same as mine... care to provide me a working plunker? – Dzak Feb 23 '18 at 10:02