javascriptangularjsmongodbangularjs-ng-repeatng-filter

How do I calculate a value based on items in a filtered angularjs repeater


I'm building a scoring system and am trying to calculate a score based on values in a separate collection. I've been using this example: Calculating sum of repeated elements in AngularJS ng-repeat , but haven't been able to get it to work as I believe they're using one collection and not two.

Here is my template using the suggestions from the question above:

<div>{{parent.id}}</div>
<div>{{ getTotal() }}</div>
<div ng-repeat="child in children | orderBy: '-postedTime' | filter: {parentId: parent.id}">
  <div>{{child.score}}</div>
</div>

The js:

$scope.getTotal = function(){
var total = 0;
for(var i = 0; i < $scope.children.length; i++){
    var score = $scope.child.score[i];
    total += (child.score);
}
return total;
}

Is there a way to sum all the scores from the filtered children and display on the parent?


Solution

  • You can take the filter response

    ng-repeat="child in children | filter: {parentId: parent.id} as kids"

    using as syntax in your children filter and use it in a sum filter which will display the sum of the scores of all children for a parent.

    var app = angular.module('plunker', []);
    
    angular.module('plunker')
      .controller('MainCtrl', function($scope) {
    
    
        $scope.totalScore = 0;
    
        $scope.parents = [{
          id: 1
        }, {
          id: 2
        }]
    
        $scope.children = [{
          parentId: 1,
          score: 25
        }, {
          parentId: 1,
          score: 25
        }, {
          parentId: 1,
          score: 25
        }, {
          parentId: 2,
          score: 25
        }];
    
      })
    
    
    app.filter('sum', function() {
      return function(kids) {
        var total = 0;
        if (kids) {
          for (i = 0; i < kids.length; i++) {
            total = total + kids[i].score;
          };
        }
        return total;
      };
    });
    <!DOCTYPE html>
    <html ng-app="plunker">
    
    <head>
      <meta charset="utf-8" />
      <title>AngularJS Plunker</title>
      <link data-require="bootstrap-css@3.3.6" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
      <script>
        document.write('<base href="' + document.location + '" />');
      </script>
      <link rel="stylesheet" href="style.css" />
      <script data-require="angular.js@1.4.x" src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9"></script>
      <script data-require="ui-bootstrap@*" data-semver="1.3.2" src="https://cdn.rawgit.com/angular-ui/bootstrap/gh-pages/ui-bootstrap-tpls-1.3.2.js"></script>
      <script src="app.js"></script>
      <script src="accounts.js"></script>
      <script src="controller.js"></script>
    </head>
    
    <body ng-controller="MainCtrl">
      <div ng-repeat="parent in parents">
        <div>parent id : {{parent.id}}</div>
        <div>total child scores : {{ kids | sum }}</div>
        <div ng-repeat="child in children | filter: {parentId: parent.id} as kids">
          <div>child Scores : {{child.score}}</div>
        </div>
      </div>
    
    
    </body>
    
    </html>

    P.S : i did not have the exact JSON for parents and children so i have removed postedTime in children but you can use it in your actual code.