Angular nested ng-repeat filter items matching parent value

10,565

Solution 1

There are a couple of ways you could do it... You could create a function to return just the children:

$scope.getChildren = function(parent) {
  var children = [];
  for (var i = 0; i < arr2.length; i++) {
    if (arr2[i].parent_id == parent.id) {
      children.push(arr2[i]);
    }
  }
  return children;
};

html:

<div ng-repeat="child in getChildren(parent)">

You could define a filter to do the same thing:

myApp.filter('children', function() {
  return function(input, parent) {
    var children = [];
    for (var i = 0; i < input.length; i++) {
      if (input[i].parent_id == parent.id) {
        children.push(input[i]);
      }
    }
    return children;
  };
});

html:

<div ng-repeat="child in arr2|children:parent">

Both of those methods will execute every digest cycle though. If you have a large list of elements you would definitely want to improve performance. I think the best way would be to pre-process those results when you get them, adding a children array to each object in arr1 with only its children (here using array.filter instead of for loop and array.forEach):

arr1.forEach(function(parent) {
  parent.children = arr2.filter(function(value) {
    return value.parent_id === parent.id;
  };
});

Then in the html you are already working with the parent so you can repeat over its children property:

<div ng-repeat="child in parent.children">

Solution 2

Instead of using filters, data-ng-if can achieve the same result.

<div data-ng-repeat="parent in arr1">
  <span>{{parent.title}}<span>
  <div data-ng-repeat="child in arr2" data-ng-if="child.parent_id == parent.id">
    <li>{{child.body}}</li>
  </div>
</div>
Share:
10,565
davet
Author by

davet

Updated on July 23, 2022

Comments

  • davet
    davet over 1 year

    I am passing in 2 arrays to my view. I would like my nested loop to only display where it's parent_id value matches the parent.id. Eg.

    arr1 = {"0":{"id":326,"parent_id":0,"title":"Mellow Mushroom voucher","full_name":"Patrick","message":"The voucher says $10 Voucher; some wording on the printout says, \"This voucher is valid for $20 Pizza\" but my purchase price or amount paid also says $20. Shouldn't that be $10","type":"Deals"}};
    arr2 = {"0":{"id":327,"parent_id":326,"title":"Re: Mellow Mushroom voucher","full_name":"Patrick Williams","message":"Some message here","type":null};
    
    ...
    <div data-ng-repeat = "parent in arr1">
    <span>{{parent.title}}<span>
        <div data-ng-repeat="child in arr2 | only-show-where-child.parent_id == parent.id">
            <li>{{child.body}}</li>
        </div>
    </div>
    

    Is this possible/best practice in angular of should I be filtering the object in node before passing it into angular? Thank you!

  • davet
    davet over 9 years
    Thank you for your versatile answer. Works perfectly!
  • Akash Agrawal
    Akash Agrawal over 7 years
    You sir, are a gem!