1
--**app.component.ts**
import { Component,OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';


@Component({
  selector: 'my-app',
  templateUrl:'./app.component.html'
})
export class AppComponent implements OnInit {
  Tree: any;
  private searchText$ = new Subject<string>();
  ngOnInit() {
    this.Tree = this.myTree;
  }

  myTree  = [
    { name: "parent1", subnodes: [{ name: "parent1_child1", subnodes: [{ name: "parent_child1_child1", subnodes: [] }] },{ name: 'parent1_child2', subnodes: [] }]  },
      {
          name: "secondparent2",
          subnodes: [
            { name: "secondparent2_child1", subnodes: [] }
          ]
      },
        {
          name: "thirdparent3",
          subnodes: [
              {
              name: "Chandigarh3",
                  subnodes: [
                    { name: "parent3_child1_child1", subnodes: [] }
                  ]
              }
          ]
      }
  ];

  filter(name: string):any {

    this.Tree = this.myTree.filter(data => data.name.match(name) || (data.subnodes.filter(subnode => (subnode.name.match(name))).length > 0) ? true:false);

  }

  search(input: string, data: any): boolean {
   let output= data.subnodes.filter(subdata => (subdata.name.match(name)))
   if (output != undefined && output.length > 0) {
     return true;
   }
   else {
     return false;
   }

    }

  }


--**app.component.html**
<h1>Tree as UL</h1>
<tree-view [treeData]="Tree"></tree-view>
<input   type="text"  (keyup)="filter($event.target.value)"  />

I am able to filter first parent nodes and corresponding subnodes but after that how to filter subnodes? I have written search function so i can invoke search method from filter method by passing the input and tree , I want to use search method recursively

1
  • I added the answer Commented Feb 15, 2018 at 16:52

1 Answer 1

1

This has nothing to do with Angular in particular, but with pure Javascript I managed to write this code that uses tail recursion and gets the job done:

function walkNodes(nodes, term) {
    let hasValue = false;

    nodes.forEach(node => {
        if (searchTree(node, term)) {
        hasValue = true; 
        return;
      };
    });

    return hasValue;
  }

  function searchTree(tree, term) {
    if (tree.name === term) { return true; }

    if ((tree.subnodes && tree.subnodes.length)) {
      return walkNodes(tree.subnodes, term);
    } 

    return false;
  }

  console.log(walkNodes(myTree, 'parent1_child2')); // true
  console.log(walkNodes(myTree, 'secondparent2_child1')); // true
  console.log(walkNodes(myTree, 'secondparent2_child12')); // false

https://jsfiddle.net/efdou6q1/

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

4 Comments

Thanks Boris Lobanov, I will try to implement in my solution
Your logic is correct but in angular how to bind the tree , we need to bind every time when user types something in Inputbox or textbox
what do you mind by "binding" the tree? your own implementation simply returns true or false, so as mine. you can simply call the same filter method, just call the walkNodes method with your whole tree and the term that user inputs
@BorisLobanov could you please give example, because I'm having same issue, I tired to call it like this this.SearchelementTree = this.SearchelementTree.filter(items => this.walkNodes(items, event));

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.