Ion-checkbox model not updating from ionchange

Hey there!
This is how I create a list with checkboxes to check/uncheck employees. I am binding the checked property of an employee to the checkbox.

<ion-list>
    <ion-item *ngFor="let employee of employees; let i = index">
        <ion-label>{{employee.name}}</ion-label>

        <ion-checkbox  value="{{employee.id}}"  
                                 [(ngModel)]="employee.isChecked"
                                 (ionChange)="emplsChange($event.detail.checked, i)"></ion-checkbox>
    </ion-item>
</ion-list>

However, when the checkbox is changed, I want to check if it can be checked or has to be false. In order to do that, I set the isChecked property of the selected employee to false after I’ve checked the conditions.

    emplsChange(detail: boolean, index: number) {
        const newEmployees: IEmployee[] = this.employees;
        this.employees = [];
        // get all checked employees
        const checkedEmpls = newEmployees.filter(e => e.isChecked).length;
        
        newEmployees[index].isChecked = detail && checkedEmpls === this.needdedEmpls ? false : detail;

        this.employees = newEmployees;
    }

Now, the thing is, that if the condition is true and I set the isChecked to false it works correctly and the checkbox is not checked. But only on the first time. If I check the same employee again the isChecked is set to false but on the UI it is checked.
I’ve tried to solve this by using (ngModelChange) instead of (ionChange) but it did nothing to it.

So the main Problem is, that the UI is not properly updated, when I set the ion-checkbox-Model in the onchange method of the component. Can one of you see another problem? Did someone experienced the same? CaN Som3One plZ HeLp!1!!!11

Thx

I haven’t really studied your html closely, but looking at this typescript, I see numerous problems, I think:

emplsChange(detail: boolean, index: number) { 
    const newEmployees: IEmployee[] = this.employees; 

I assume the newEmployees is supposed to be a local copy of the this.employees array. But this code does not copy the array: it just makes a new reference to it. If you want a new copy, you have to do that explicitly. Do a google search for how to make a true full deep copy of an array.

this.employees = []; // get all checked employees this might set your array back to nothing – including the newEmployees array that pointed to the same thing – I’m not sure. Put some console.logs in to find out the contents of newEmployees after this line.

const checkedEmpls = newEmployees.filter(e => e.isChecked).length; 

I think you are trying to get an array of employees that were checked in the UI. However, what you are getting is an integer – the length of the array.

newEmployees[index].isChecked = detail && checkedEmpls === this.needdedEmpls ? false : detail; 

This code is quite confusing to me. The first part is an assignment and the second part is a comparison. Did you mean

newEmployees[index].isChecked = ( detail && ( checkedEmpls === this.needdedEmpls ? false : detail ) ) ;

(fully parenthesized) ?

If so, you are trying to set isChecked either to false or detail, which seems weird to me. You might want to check this logic and turn the code into an if statement. Or, maybe the logic is correct, and I just don’t understand it.

Hope this helps! Good luck!

2 Likes

@VictorNorman thx for your quick and detailed answer. so problem was the deep copy :man_facepalming: How could I forget that. thanks a lot. the rest works how I want it to work.
The following line is the amount of checked Employees and this is what I want

const checkedEmpls = newEmployees.filter(e => e.isChecked).length; 

This

newEmployees[index].isChecked = detail && checkedEmpls === this.needdedEmpls ? false : detail;

is equal to
´´´
if(detail && checkedEmpls === neededEmpls) {
newEmployees[index].isChecked=false;
} else {
newEmployees[index].isChecked=detail;
}
´´´

But nevermind thx again for helpinng me out :+1:

No problem.

(YOu might have misspelled needdedEmpl in one place, too… :slight_smile:

1 Like