javascriptangularjsangularjs-ng-change

ng-change not getting called on checkbox


I have a select dropdown. Upon selecting each value in dropdown, checkboxes are created using ng-repeat. All the values in the dropdown are supposed to be selected and corresponding checkboxes are stored in an array when a checkbox is checked using ng-change on the checkbox.

When I change back to a previous dropdown value, I am checking if the checkboxes are already there in the array used to store checked values and then check them using ng-check on load.

But when I uncheck the loaded checkboxes, SOMETIMES the ng-change is not called. I don't understand why.

When I check and uncheck it again, then it works.

Storing and removing checked values on checkbox change:

    $scope.checkChanged = function(isChecked, flat){
        //debugger;
        console.log("check change");
        if(isChecked != -1){
            let tempArray = [];
            for(let i=0; i<$scope.userEventData.selectedFlats.length; i++){
                tempArray.push($scope.userEventData.selectedFlats[i].flat_id);
            }
            if(!tempArray.includes(flat.flat_id)){
                $scope.userEventData.selectedFlats.push(flat);
                console.log("pushed new", flat.flat_no);
            }
        }else{
            $scope.userEventData.selectedFlats = $scope.userEventData.selectedFlats.filter(function(f){
                console.log(f, flat.flat_id);
                return f.flat_id != flat.flat_id
            });
            console.log("removed", flat.flat_no);
        }
        console.log($scope.userEventData.selectedFlats, "pushed check");
}

$scope.flatsArray is the array used to generate checkboxes using ng-repeat. Set checkbox to checked or unchecked based on array storing checked values($scope.userEventData.selectedFlats):

.then(function successCallback(response){ 
        $scope.flatsArray = response.data.body.Data;

        for(let d=0; d< $scope.flatsArray.length; d++){

            $scope.flatsArray[d].isChecked = false;

        }

        if($scope.userEventData.selectedFlats.length){
            let tempSelectedFlat = [];
            for(let j=0; j<$scope.userEventData.selectedFlats.length; j++){
                tempSelectedFlat.push($scope.userEventData.selectedFlats[j].flat_id);
            }
            console.log(tempSelectedFlat,"tempSelectedFlat");

            /** If present in selectedFlats set ng-checked to true **/
            for(let d=0; d< $scope.flatsArray.length; d++){
                console.log(d, "d");
                console.log($scope.flatsArray[d].flat_id, "$scope.flatsArray[d].flat_id");
                console.log(tempSelectedFlat.includes($scope.flatsArray[d].flat_id));
                if(tempSelectedFlat.includes($scope.flatsArray[d].flat_id)){
                    $scope.flatsArray[d].isChecked = true;
                }else{
                    $scope.flatsArray[d].isChecked = false;
                }

            }
        }else{
            for(let d=0; d< $scope.flatsArray.length; d++){

                $scope.flatsArray[d].isChecked = false;

            }
        }

The html:

    <div class="ScrollStyle">
   <div ng-repeat="flat in flatsArray" class="row" style="width:90%;">
      <div class="col-md-2">
         <input class="" name="{{flat.flat_no}}" 
            type="checkbox" ng-true-value="{{flat.flat_id}}" 
            ng-false-value="'-1'" 
            ng-checked="flat.isChecked"
            ng-change="checkChanged(sFlats[$index], flat)" ng-model="sFlats[$index]" />
      </div>
      <div class="col-md-10"><label for="{{flat.flat_no}}">{{flat.flat_no}}</label></div>
   </div>
</div>

$scope.flatsArray:

   0: {flat_id: "9", flat_no: "1", isChecked: false, $$hashKey: "object:62"}
1
:
{flat_id: "10", flat_no: "2", isChecked: false, $$hashKey: "object:63"}

Solution

  • If you look at the definition of ng-checked and ng-model, you are not suppose to use them both. Ideally you should just use ng-model. ng-model="flat.isChecked" . If you add some log statements you will know a bit more as to what is being fired or not.

    Here is some information you may enjoy: Angularjs: checkbox and ng-change

    ng-checked will modify the checked attribute, but if you want binding, ng-model will be the best. I almost exclusively use ng-model in all of my forms.

    The Logs will give you more insight to know what is actually being fired. If something is not being fired, then it means the event is not wired correctly.