1

I have an array of items that I'm repeating over using ng-repeat and am using group filter

this is my array

var items = [
   { product_id : 1, quantity : 2 }
   { product_id : 1, quantity : 3 }
   { product_id : 2, quantity : 2 }
   { product_id : 3, quantity : 4 }
   { product_id : 2, quantity : 8 }
];

I would like an ng-repeat that results in the following presentation

| product_id 1 | quantity 5 |
| product_id 2 | quantity 10 |
| product_id 3 | quantity 4 |

Any suggestions?

1
  • why not use something like lodash to preprocess/group the data? Commented Feb 14, 2015 at 5:12

3 Answers 3

2

Although it's old question I saw that I can answer this more clearly.

I'm using angular-filter module to get groupBy filter.

angular.module('app', ['angular.filter']).
controller('ctrl', function($scope) {
  $scope.data = [
    { product_id : 1, quantity : 2 },
    { product_id : 1, quantity : 3 },
    { product_id : 2, quantity : 2 },
    { product_id : 3, quantity : 4 },
    { product_id : 2, quantity : 8 }
  ];
}).
filter('total', function() {
  return function(arr, prop) {
    return arr.reduce(function(previousValue, currentObj) {
      return previousValue + currentObj[prop];
    }, 0);
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-filter/0.4.7/angular-filter.js"></script>

<div data-ng-app="app" data-ng-controller="ctrl">
  <div data-ng-repeat="(key, value) in data | groupBy : 'product_id'">
    | product_id {{key}} | quantity {{value | total: 'quantity'}}
  </div>
</div>

Update

There is a better way to calc the sum of each group thanks, again, to angular-filter (and @toddbranch). To calculate the total you can use map and sum filter. like this:

{{value | map: 'quantity' | sum}}

And the full demo:

angular.module('app', ['angular.filter']).
controller('ctrl', function($scope) {
  $scope.data = [
    { product_id : 1, quantity : 2 },
    { product_id : 1, quantity : 3 },
    { product_id : 2, quantity : 2 },
    { product_id : 3, quantity : 4 },
    { product_id : 2, quantity : 8 }
  ];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-filter/0.4.7/angular-filter.js"></script>

<div data-ng-app="app" data-ng-controller="ctrl">
  <div data-ng-repeat="(key, value) in data | groupBy : 'product_id'">
    | product_id {{key}} | quantity {{value | map: 'quantity' | sum}}
  </div>
</div>

Sign up to request clarification or add additional context in comments.

Comments

0

Trying nesting the ng-repeat tag in the html tags like so,

<div ng-repeat 1>
  <div ng-repeat 2>
    <!-- where you need the data -->
  </div>
</div>

Comments

0

You need to create your own filter. Need some work on below filter to get the addition of quantity with same product_id.

Markup

<div ng-repeat="i in items | orderBy: 'product_id' |groupBy:'product_id':'quantity'">
   {{i.product_id}}| {{i.quantity}}
</div>

Filter

app.filter('groupBy', function() {
    return function(values, property1, property2) {
        var groupByArray = [];
        console.log("Initialize");
        angular.forEach(values, function(value, index) {
            var lengthOfGroupBy = groupByArray.length;
            if (lengthOfGroupBy == 0 || groupByArray[lengthOfGroupBy - 1][property1] != value[property1]) {
                groupByArray.push(value);
            }
        });
        return groupByArray;
    }
});

Working Fiddlle

UPDATE

I tried further and successfully implement the thing which you want, it works but there is error in console which says "Error: 10 $digest() iterations reached. Aborting!”

Here is my Updated Fiddle with error in console.

I found the solution on SO that works for same problem.

3 Comments

Initially the lengthOfGroupBy is 0 so the result of if statement is always false..
@UlukBiy thats my bad.Thanks for heads up..I pasted wrong code(the one which i was trying for quantity addition).
@rslhdyt does it helpful to you?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.