wilson wilson - 18 days ago 5
AngularJS Question

AngularJS: Summing nested objects from multiple objects

Based in the following table I need to get the total of all subtotals.

I have tried to use the same sumByKey filter but I does't work.
Plus, the sum of all subtotals must be based on the result of the filter, it means, If we have two results (two categories) the sum of subtotals must be based on those objects. Any idea?

html

<table border="1">
<thead>
<tr>
<th>#</th>
<th>Category</th>
<th>Products with quantities</th>
<th>Subtotal of quantities</th>
</tr>
</thead>
<tbody align="center">
<tr data-ng-repeat="category in categories | filter:search">
<td>{{$index+1}}</td>
<td>{{category.name}}</td>
<td>{{category.products}}</td>
<td>{{category.products | sumByKey:'quantity'}}</td>
</tr>
</tbody>
<thead align="right">
<tr>
<td colspan="3"><strong>Total</strong></td>
<td></td>
</tr>
</thead>
</table>


angularjs

var app = angular.module("app", []);
app.controller("controllerApp", function($scope, $http){
$http.get("categories.json").success(function(data) {
$scope.categories = data;
});
});

app.filter('sumByKey', function () {
return function (data, key) {
if (typeof (data) === 'undefined' || typeof (key) === 'undefined') {
return 0;
}
var sum = 0;
for (var i = data.length - 1; i >= 0; i--) {
sum += parseInt(data[i][key]);
}
return sum;
}
});

Answer

It can be done with angular also.

Example : http://plnkr.co/edit/zhTtoOjW7J1oumktlvFP?p=preview

HTML:

<table border="1">
      <thead>
        <tr>
          <th>#</th>
          <th>Category</th>
          <th>Products with quantities</th>
          <th>Subtotal of quantities</th>
        </tr>
      </thead>
      <tbody align="center">
        <tr data-ng-repeat="category in filterValues=(categories | filter:search)">
          <td>{{$index+1}}</td>
          <td>{{category.name}}</td>
          <td>{{category.products}}</td>
          <td>{{category.products | sumByKey:'quantity'}}</td>
        </tr>
      </tbody>
      <thead align="right">
        <tr>
          <td colspan="3"><strong>Total</strong></td>
          <td>{{filterValues | sumOfValue:'quantity'}}</td>
        </tr>
      </thead>
    </table>

JS:

// Code goes here
var app = angular.module("app", []);
app.controller("controllerApp", function($scope, $http) {
  $http.get("categories.json").success(function(data) {
    $scope.categories = data;
  });
});

app.filter('sumByKey', function() {
  return function(data, key) {
    if (typeof(data) === 'undefined' || typeof(key) === 'undefined') {
      return 0;
    }
    var sum = 0;
    for (var i = data.length - 1; i >= 0; i--) {
      sum += parseInt(data[i][key]);
    }
    return sum;
  }
});

app.filter('sumOfValue', function() {
  return function(data, key) {
    if (angular.isUndefined(data) || angular.isUndefined(key)) {
      return 0;
    }
    var sum = 0;
    for (var i = 0; i < data.length; i++) {
      var value = data[i];
      if (!angular.isUndefined(value)) {
        for (var j = 0; j < value.products.length; j++) {
          sum += parseInt(value.products[j][key]);
        }
      }
    }
    return sum;
  }
});