1

I am posting this because I never found a precise answer for filtering nested objects (tree sturcture).

Let's say we have an JSON tree structure that looks like this:

$scope.tree = [{
    id: 1,
    parent_id: 0,
    name: 'Root Item',
    items: [
              {
               id: 2, 
               parent_id: 1, 
               name: '1st Child of 1'
              },
              {
               id: 3, 
               parent_id: 1, 
               name: '2nd Child of 1'
              },
              {
               id: 4, 
               parent_id: 1, 
               name: '3rd Child of 1',
               items:[
                   {
                    id:5, 
                    parent_id: 4, 
                    name:'1st Child of 5'
                    },
                   {
                    id:6, 
                    parent_id: 4, 
                    name:'2nd Child of 5'
                    }
               ]}
           ]
    }]

How do we traverse the tree with a filter to get object with id 6 for example?

1 Answer 1

6

If we use the following filter for example:

<div data-ng-init="selectedItem = (tree | filter:{id:6})">
  <h1>The name of item with id:6 is selectedItem.name</h1>
</div>

It will only iterate through the first level in which will only find id:1. So, in order to get nested level objects we must use a recursive filter like this one:

angular.module("myApp",[])
   .filter("filterTree",function(){
       return function(items,id){
          var filtered = [];
          var recursiveFilter = function(items,id){
              angular.forEach(items,function(item){
                 if(item.id === id){
                    filtered.push(item);
                 }
                 if(angular.isArray(item.items) && item.items.length > 0){
                    recursiveFilter(item.items,id);              
                 }
              });
          };
          recursiveFilter(items,id);
          return filtered;
       }; 
    });
});

So, to use this filter in the markup you would call it like this:

<div data-ng-init="selectedItem = (tree | filterTree:6)">
  <h1>The name of item with id:6 is selectedItem.name</h1>
</div>

Hope you find this useful, it took me some time to digest recursive filters.

Of course, this filter works to get 1 item since it returns [0] first object of filtered array. But if you want it to return more than 1 result you'll have to remove only that [0] at the return function and then use ng-repeat to iterate over filtered resutls.

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

1 Comment

Brilliant, the exact recursion I was looking for!

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.