Angular recursive template list turns into infinite recursion if object.value is used instead of object

Viewed 389

I want to render a recursive list in an Angular Template.

This is the data attribute in the component.ts:

data =  [
{
  type: "TEXT",
  key: "text_key_1", 
  value: "text_value_1",
},
{
  type: "INTEGER",
  key: "int_key_1",
  value: 42,
},
{
  type: "ARRAY",
  key: "array_key_1",
  value: [
    {
      type: "TEXT",
      key: "text_key_2", 
      value: "text_value_2",
    },
    {
      type: "TEXT",
      key: "text_key_3", 
      value: "text_value_3",
    },
  ]
}
]

This is how my Template looks like:

<ul>
  <ng-template #recursiveList let-data>
    <li *ngFor="let item of data">
      <ng-container [ngSwitch]="item.type">
        <ng-container *ngSwitchCase="'TEXT'">{{item.key}}: {{item.value}}</ng-container>
        <ng-container *ngSwitchCase="'INTEGER'">{{item.key}}: {{item.value}}</ng-container>
        <ng-container *ngSwitchCase="'ARRAY'">
          {{item.key}}:
          <ul>
            <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: item.value }"></ng-container>
          </ul>
        </ng-container>
      </ng-container>
    </li>
  </ng-template>
  <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: data }"></ng-container>
</ul>

This is how the final result looks like:

nested list result

The problem is that data is nested into another object mainData:

mainData =  { data: [
{
  type: "TEXT",
  key: "text_key_1", 
  value: "text_value_1",
},
{
  type: "INTEGER",
  key: "int_key_1",
  value: 42,
},
{
  type: "ARRAY",
  key: "array_key_1",
  value: [
    {
      type: "TEXT",
      key: "text_key_2", 
      value: "text_value_2",
    },
    {
      type: "TEXT",
      key: "text_key_3", 
      value: "text_value_3",
    },
  ]
}
]
}

If I now update all occurences of data to mainData.data in the template (eg. let-data to let-mainData.data), I get an infinite recursion. How can I fix it? I think there is a problem with the ".". I also don't know exactly what the code does bcs I copied it from somewhere. What is purpose of let-data and the $implicit? Thanks a lot!

1 Answers

May be this could help you.

Typescript

data: any[] = mainData.data;

HTML

<ul>
          <ul *ngFor="let item of data">  
             <ng-container [ngTemplateOutlet]="recursiveListTmpl" [ngTemplateOutletContext]="{ data: item }">
             </ng-container>
          </ul>
    
    <ng-template #recursiveList let-data="data">
            <li *ngFor="let item of data">
              <ng-container [ngSwitch]="item.type">
                <ng-container *ngSwitchCase="'TEXT'">{{item.key}}: {{item.value}}</ng-container>
                <ng-container *ngSwitchCase="'INTEGER'">{{item.key}}: {{item.value}}</ng-container>
                <ng-container *ngSwitchCase="'ARRAY'">
                  {{item.key}}:
                  <ul>
                    <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: item.value }"></ng-container>
                  </ul>
                </ng-container>
              </ng-container>
            </li>
    </ng-template>
</ul>
        
    
Related