mpsbhat
mpsbhat

Reputation: 2773

sum of values in a list using angular way

I have a short piece of sample here where myself trying to get total of values in angular way as,

<div id="app" ng-app="myApp" ng-controller="myCtrl" ng-init="total = 0">
  <ul>
      <li  ng-repeat="x in myarr" >  {{x.val}} 
     <span ng-if="$last">, Total - {{total = total+x.val}}</span>
      </li>
  </ul>
</div>

But total is incorrect. How can it be achieved?

EDIT: Myself trying to get total within the ng-repeat loop beside last element. There is an accepted answer in this question and below answer also work in same logic. But In that method, the function getTotal() will call myarr.length times and each time the array loops in controller right? So as per example in the question, array will loop completely 6 times (myarr.length + once in ng-repeat ie, 5+1). Do i wrong?

Upvotes: 0

Views: 3578

Answers (3)

rejo
rejo

Reputation: 3350

Try this method, no function used in controller , using ng-init in ng-repeat

angular.module('myApp', []).controller('myCtrl', function($scope) {

$scope.myarr = [{id: 1, val: 500},{id: 2,val: 300},{id: 3,val: 200},{id: 4,val: 600},{id: 5,val: 100}];

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div id="app" ng-app="myApp" ng-controller="myCtrl" ng-init="total=0">
  <ul >
      <li ng-repeat="x in myarr" ng-init="$parent.total = $parent.total + (x.val)"> {{x.val}} 
      <span ng-if="$last">{{total}}</span>
      </li>
  </ul>
</div>
Another method ,

Use array.reduce to add sum of array Link

angular.module('myApp', []).controller('myCtrl', function($scope) {

$scope.myarr = [{id: 1, val: 500},{id: 2,val: 300},{id: 3,val: 200},{id: 4,val: 600},{id: 5,val: 100}];
$scope.addTotal = function(){
var sum = $scope.myarr.reduce($scope.add);
return sum.val;
}
$scope.add = function(a,b){
 return {val:a.val + b.val};
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div id="app" ng-app="myApp" ng-controller="myCtrl" ng-init="total=0">
  <ul >
      <li ng-repeat="x in myarr" >  {{x.val}} 
      <span ng-if="$last">{{addTotal()}}</span>
      </li>
  </ul>
</div>

Upvotes: 1

Stark Buttowski
Stark Buttowski

Reputation: 1849

You can use angular.forEach to loop and have you total count.

angular.module('myApp', []).controller('myCtrl', function($scope) {
  $scope.total = 0;
 $scope.myarr = [{id: 1, val: 500},{id: 2,val: 300},{id: 3,val: 200},{id: 4,val: 600},{id: 5,val: 100}];
  angular.forEach($scope.myarr, function(value){$scope.total+=value.val});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div id="app" ng-app="myApp" ng-controller="myCtrl">
  <ul >
      <li ng-repeat="x in myarr" >  {{x.val}} 
      <span ng-if="$last">{{total}}</span>
      </li>
  </ul>
</div>

Upvotes: 1

Viral Shah
Viral Shah

Reputation: 47

Try doing all calculations in angular controller itself and storing it in varaible. But if you are worried about values in array constantly changing you can also use a calcTotal function in your controller. Also ng-repeat should be on li and not ul.

<div id="app" ng-app="myApp" ng-controller="myCtrl" ng-init="total = 0">
  <ul >
      <li ng-repeat="x in myarr">  {{x.val}} 
     <span ng-if="$last">, Total - {{getTotal()}} or {{totalValue}}</span>
      </li>
  </ul>
</div>

Your controller will be like

angular.module('myApp', []).controller('myCtrl', function($scope) {
 $scope.myarr = [{id: 1, val: 500},{id: 2,val: 300},{id: 3,val: 200},{id: 4,val: 600},{id: 5,val: 100}];
 //first approach
 $scope.totalValue = 0;
 for(i=0;i<$scope.myarr.length;i++){
 if($scope.myarr[i] && $scope.myarr[i].val)
    $scope.totalValue+=$scope.myarr[i].val;
 }

 //OR

 //second approach
 $scope.getTotal = function(){
 var total = 0;
 for(i=0;i<$scope.myarr.length;i++){
 if($scope.myarr[i] && $scope.myarr[i].val)
    total+=$scope.myarr[i].val;
 }
 return total;
 }
});

If you are using variable approach, you will have to explicitly calculate $scope.getTotal everytime the array values change. By the function approach it will happen itself, but binding functions on UI is little expensive as they keep re-calculating on every digest cycle.

Upvotes: 1

Related Questions