When working with real world applications, it’s often required to render a tree like structure. Say a tree view of directories in a file system or a finely categorized list of items. Something like this.

Let’s create one for ourselves using Angular 2.

For the sake of brevity, I have omitted common import statements and other boilerplate code.

The Idea

It’s pretty simple. To parse infinite trees, we do recursion. To do that, we call a function within that function until a breaking condition is met.

The same idea works for templates. We render our component, within the same component and let it do the same till the tree meets it’s leaf nodes.

Skeleton App & Data

Here’s how our App component looks like.

@Component({ selector: 'my-app', template: ` <div> <h2>Hello {{name}}</h2> <ui-tree [data]="data" [key]="key"></ui-tree> </div> ` }) export class App { name:string; key: string = 'categories'; data: Array<Object> = [ { name: "Beverages", categories: [ { name: "Pepsi", categories: [] }, { name: "CocaCola", categories: [ { name: "Coke Diet", categories: [] }, { name: "Coke Zero", categories: [] } ] } ] }, { name: "Footwear", categories: [ { name: "Sneakers", categories: [] } ] } ]; constructor() { this.name = 'Rendering Nested Trees in Angular 2' } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 @ Component ( { selector : 'my-app' , template : ` < div > < h2 > Hello { { name } } < / h2 > < ui - tree [ data ] = "data" [ key ] = "key" > < / ui - tree > < / div > ` } ) export class App { name : string ; key : string = 'categories' ; data : Array < Object > = [ { name : "Beverages" , categories : [ { name : "Pepsi" , categories : [ ] } , { name : "CocaCola" , categories : [ { name : "Coke Diet" , categories : [ ] } , { name : "Coke Zero" , categories : [ ] } ] } ] } , { name : "Footwear" , categories : [ { name : "Sneakers" , categories : [ ] } ] } ] ; constructor ( ) { this . name = 'Rendering Nested Trees in Angular 2' } }

The code is pretty simple.

We include < ui - tree > component in our app template. We’ll see the detailed code for < ui - tree > in a moment.

component in our app template. We’ll see the detailed code for in a moment. We have key which is the property name in our data that increases the depth of the tree. In our case, data is an array of objects and each object contains name and categories array. This categories array is what gives depth to our tree. So key here is “categories”.

UI Tree Component

Below is what the tree component itself looks like. It accepts two parameters, the data and the key . It then calls itself in the template and passes the inner categories array to render another sub-tree.

@Component({ selector: "ui-tree", template: ` <ul *ngIf="items.length"> <li *ngFor="let item of items"> {{item.name}} <ui-tree *ngIf="item[key].length" [key]="key" [data]="item[key]"></ui-tree> </li> </ul> ` }) export class UiTree { @Input('data') items: Array<Object>; @Input('key') key: string; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @ Component ( { selector : "ui-tree" , template : ` < ul * ngIf = "items.length" > < li * ngFor = "let item of items" > { { item . name } } < ui - tree * ngIf = "item[key].length" [ key ] = "key" [ data ] = "item[key]" > < / ui - tree > < / li > < / ul > ` } ) export class UiTree { @ Input ( 'data' ) items : Array < Object > ; @ Input ( 'key' ) key : string ; }

Key thing to notice in this code is recursive inclusion of the <ui-tree> component in the template.

<ui-tree *ngIf="item[key].length" [key]="key" [data]="item[key]"></ui-tree> 1 < ui - tree * ngIf = "item[key].length" [ key ] = "key" [ data ] = "item[key]" > < / ui - tree >

Putting Things Together…