Skip to content

Instantly share code, notes, and snippets.

@arniebradfo
Last active October 22, 2024 18:40
Show Gist options
  • Save arniebradfo/5cf89c362cc216df6fc1d9ca4d536b72 to your computer and use it in GitHub Desktop.
Save arniebradfo/5cf89c362cc216df6fc1d9ca4d536b72 to your computer and use it in GitHub Desktop.
Angular *ngFor recursive list tree template
<h1>Angular 2 Recursive List</h1>
<ul>
<ng-template #recursiveList let-list>
<li *ngFor="let item of list">
{{item.title}}
<ul *ngIf="item.children.length > 0">
<ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: item.children }"></ng-container>
</ul>
</li>
</ng-template>
<ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: list }"></ng-container>
</ul>
import { Component } from '@angular/core';
@Component({
selector: 'yourapp-any',
templateUrl: './any.component.html' // the magic's in here
})
export class AnyComponent {
constructor() { }
// its just list data from here down
public list = [
{
title: 'childless',
children: []
},
{
title: 'great grandparent',
children: [
{
title: 'childless grandsibiling',
children: []
},
{
title: 'grandparent',
children: [
{
title: 'childless sibiling',
children: []
},
{
title: 'another childless sibiling',
children: []
},
{
title: 'parent',
children: [
{
title: 'child',
children: []
},
{
title: 'another child',
children: []
},
]
},
{
title: 'another parent',
children: [
{
title: 'child',
children: []
},
]
},
]
},
{
title: 'another grandparent',
children: [
{
title: 'parent',
children: [
{
title: 'child',
children: []
},
{
title: 'another child',
children: []
},
{
title: 'a third child',
children: []
},
{
title: 'teen mother',
children: [
{
title: 'accident',
children: []
},
]
},
]
},
]
},
]
},
];
}
@Gargamil
Copy link

Awesome, thanks!

But stay in mind:
<li *ngFor="let item of list">
can NOT be changed to something like
<li *ngFor="let item of list.children">.

In the second case, only the first level elements will be shown. (Not deeper levels..)

@Gwoks
Copy link

Gwoks commented Apr 12, 2018

Thanks man!! works perfect...

@alexnoise79
Copy link

Hi, i was working on a similar solution to manage a recursive menu, but i have some problems with routerLinkActive

did you try something similar?

@ramnithik
Copy link

If i add new children in list for dynamic process...the recursive list is crash??

@edgargomx
Copy link

great, thanks man!!, works perfect to trees list 👍

@gmullersoriba
Copy link

Nice !

@sakthikanth
Copy link

Thanks...

@diegosliver
Copy link

Thanks

@chethangowda
Copy link

not working for me getting error "ERROR RangeError: Maximum call stack size exceeded"

@danielhdz56
Copy link

not working for me getting error "ERROR RangeError: Maximum call stack size exceeded"

@chethangowda you'll get this error if you don't define the same let-variable as your *ngFor loop

so for example if your *ngFor was:
*ngFor="let navigationItem of navigationItems"
then the variable would be let-navigationItems instead of let-list

@amankumar5
Copy link

Thanks , it work fine but how to make the data two way binded using this ?

@elciospy
Copy link

The best recursive list tree!!
thank yyouuu!!

@tlavarea
Copy link

Getting the following error using Angular 8:
ERROR TypeError: templateRef.createEmbeddedView is not a function. Any help would be appreciated. Thank you.

@Darksoul7878
Copy link

Can I add nodes dynamically

@lreyessandoval
Copy link

Genial...

@joshuaM07
Copy link

Really cool. Helped me a lot. That's exactly what I had in mind, but was having trouble with the execution.
Confirmed working in Angular 11

@cybercris
Copy link

Thanks! Confirmed working in Angular 10+
Awesome example

@EABangalore
Copy link

EABangalore commented Oct 21, 2021

What if i have 2 components one <parent> another is <child> how to use them inside above code

<ul>
  <ng-template #recursiveList let-list>
    <li *ngFor="let item of list">
     <!--  commented {{item.title}} -->
      <child [item]="item"/>
      <!-- commented <ul *ngIf="item.children.length > 0"> -->
       <template>
            <parent [item]="item"/>
            <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: item.children }"></ng-container>
       </template>
      <!-- commented </ul> -->
    </li>
  </ng-template>
  <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: list }"></ng-container>
</ul> 

please help me how to do that correctly

@kkahara
Copy link

kkahara commented Jul 29, 2022

How do we do this with Angular 8 and up?

@mjpoo
Copy link

mjpoo commented Jul 25, 2024

Tip: If you don't want to have to add empty children arrays then you can check for item.children in the *ngIf:

<ul *ngIf="item.children && item.children.length > 0">

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment