I'm trying to create a recursive template an ran into a problem. My template:
<ng-template #recursiveGroups let-groups>
@for (group of groups; track group; let i = $index) {
<!-- Some stuff are shown -->
@for (subGroup of group.subGroups; track subGroup; let j = $index) {
<ng-container *ngTemplateOutlet="recursiveGroups; context:{$implicit: data[i].subGroups[j]}"></ng-container>
<!-- ALSO, SEPARATLY, TRIED: -->
<ng-container *ngTemplateOutlet="recursiveGroups; context:{$implicit: subGroup}"></ng-container>
<!-- OR: -->
<ng-container *ngTemplateOutlet="recursiveGroups; context:{groups: subGroup}"></ng-container>
}
}
</ng-template>
<ng-container *ngTemplateOutlet="recursiveGroups; context:{$implicit: data}"></ng-container>
My data looks like:
data: [
{
...,
children: [
{
...
}
],
subGroups: [
{
...,
children: [
{
...
}
],
subGroups: [
{
...,
}
],
}
],
},
...
]
Using context:{groups: <*>}
shows only the top most level.
Using context:{@implicit: <*>}
shows only the top most level and also raises error:
core.mjs:6531 ERROR TypeError: newCollection[Symbol.iterator] is not a function
What am I missing here? Thanks.
Your recursiveGroups
template expects an array, hence I don't see you need a nested @for
for the subGroups
. The template can be reused for the subGroups
iteration.
Changes:
Remove the nested @for
.
Provide the group.subGroups
to the context for the nested <ng-container>
.
<ng-template #recursiveGroups let-groups>
@for (group of groups; track group; let i = $index) {
<ng-container *ngTemplateOutlet="recursiveGroups; context:{ $implicit: group.subGroups }"></ng-container>
}
</ng-template>
Demo @ StackBlitz
You are running the forLoop at the top of the template, so there is no need for more for loops in recursion. All you need to do is to ensure the input for the recursive template remains as a array, then it will render correctly:
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule],
template: `
<ng-template #recursiveGroups let-groups>
@for (group of groups; track group; let i = $index) {
{{group.id}}
<hr/>
<ng-container *ngTemplateOutlet="recursiveGroups; context:{$implicit: group.children}"></ng-container>
<hr/>
<ng-container *ngTemplateOutlet="recursiveGroups; context:{$implicit: group.subGroups}"></ng-container>
}
</ng-template>
<ng-container *ngTemplateOutlet="recursiveGroups; context:{$implicit: data}"></ng-container>
`,
})
export class App {
name = 'Angular';
data: any = [
{
id: 1,
children: [
{
id: 2,
},
],
subGroups: [
{
id: 3,
children: [
{
id: 4,
},
],
subGroups: [
{
id: 5,
},
],
},
],
},
];
}
bootstrapApplication(App);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With