nemo_87
nemo_87

Reputation: 4781

Cannot set property of undefined in AngualrJs

I am trying to make a select all checkbox, that will on click select/deselect all other checkboxes on the page.

My HTML is like this:

<table class="table table-striped">
    <thead>
        <tr class="table-header">
            <th ng-if="!newTestSessionCtrl.formData.battery.id"><input type="checkbox" ng-click="newTestSessionCtrl.selectAllTests()" ng-model=".allSelected" /></th>
            <th>Test</th>
            <th>Available Time</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="row in newTestSessionCtrl.formData.battery.testDefinitions">
            <td ng-if="!newTestSessionCtrl.formData.battery.id"><input type="checkbox" ng-model="row.selected" ng-change="newTestSessionCtrl.optionToggled(); newTestSessionCtrl.validate()" /></td>
            <td>{{row.name}}</td>
            <td>{{(row.duration / 60) | number:0}} minutes</td>
        </tr>
    </tbody>
</table>

And this is code from my controller:

    class NewTestSessionController {
        constructor($scope, $state, resources, NewTestSessionService, formats, AuthenticationService, toastr, momentTimezone, _) {
            this.allSelected = false;
        }

        selectAllTests() {
           let isSelected = true;
           if (this.allSelected) {
              isSelected = false;
           }
           angular.forEach(this.formData.battery.testDefinitions,  function(v) {
               v.checked = !isSelected;
               this.allSelected = !isSelected;
           });
        }

        optionToggled() {
           this.allSelected = true;
           angular.forEach(this.formData.battery.testDefinitions, function(v) {
               if(!v.checked) {
               this.allSelected = false;
           }
         });
      }
   }

The problem is with allSelected variable, when I click on select all checkbox I get error about being undefined:

enter image description here

Am I trying to access it in some wrong way? When I use debugger this variable is not undefined, so I am not sure if I am even looking on right place? This problem should be easy to implement, but still I am not that good at Angular. Does someone sees the problem?

Upvotes: 0

Views: 70

Answers (2)

Pankaj Parkar
Pankaj Parkar

Reputation: 136144

Use Arrow Function instead of function() declaration.

Code

selectAllTests() {
   let isSelected = true;
   if (this.allSelected) {
      isSelected = false;
   }
   //arrow function to make current this available inside function
   angular.forEach(this.formData.battery.testDefinitions,  (v) => {
       v.checked = !isSelected;
       this.allSelected = !isSelected;
   });
}

optionToggled() {
   this.allSelected = true;
   //arrow function to make current this available inside function
   angular.forEach(this.formData.battery.testDefinitions, (v) => {
       if(!v.checked) {
       this.allSelected = false;
   }
});

Upvotes: 2

Jyothi Babu Araja
Jyothi Babu Araja

Reputation: 10282

It's the scope issue with this.

this scope is not available inside callback functions.

Assign this to another variable and use it inside the callbacks

Replace controller with this code.

class NewTestSessionController {
        constructor($scope, $state, resources, NewTestSessionService, formats, AuthenticationService, toastr, momentTimezone, _) {
            this.allSelected = false;
        }

        selectAllTests() {
           let _this = this;
           let isSelected = true;
           if (this.allSelected) {
              isSelected = false;
           }
           angular.forEach(this.formData.battery.testDefinitions,  function(v) {
               v.checked = !isSelected;
               _this.allSelected = !isSelected;
           });
        }

        optionToggled() {
           let _this = this;
           this.allSelected = true;
           angular.forEach(this.formData.battery.testDefinitions, function(v) {
               if(!v.checked) {
               _this.allSelected = false;
           }
         });
      }
   }

Upvotes: 0

Related Questions