Below data should be logically translated into list items.

{
   "text":"root",
   "children":[
      {
         "text":"Unordered Item One",
         "children":[],
         "type":"unordered-list-item"
      },
      {
         "text":"Unordered Item Two",
         "children":[],
         "type":"unordered-list-item"
      },
      {
         "text":"Unordered Item three",
         "children":[
            {
               "text":"Ordered Item A",
               "children":[],
               "type":"ordered-list-item"
            },
            {
               "text":"Ordered Item B",
               "children":[],
               "type":"ordered-list-item"
            }
         ],
         "type":"unordered-list-item"
      }
   ],
   "type":"unordered-list-item"
}

So the final output is expected like below,

<ul>
    <li>Unordered Item One</li>
    <li>Unordered Item Two</li>
    <li>Unordered Item three</li>
    <li> 
        <ol>
            <li>Ordered Item A</li>
            <li>Ordered Item B</li>
        </ol>
    </li>   
</ul>

I've created recursion component to render all these items,

In my app component,

<ng-container *ngIf="nested.type==='unordered-list-item'">
    <li>{{nested.text}}</li>
    <ul *ngIf="nested.children.length > 0">
        <app-recursion *ngFor="let child of nested.children" [children]="child.children" [text]="child.text"></app-recursion>
    </ul>
</ng-container> 

In Recursion Component,

<ng-container *ngIf="nested.type==='unordered-list-item'">
  <li>{{text}}</li>
</ng-container>

But it doesn't render the child items, Please show me what I'm doing wrong here.

Below is the working link to my project,

https://stackblitz.com/edit/angular-wvztjy?file=src%2Fapp%2Frecursion%2Frecursion.component.html

4 Answers

0
chestas On

change or remove condition in recursion component: *ngIf="nested.type==='unordered-list-item'"

  <ng-container>
      <li>{{text}}</li>
    </ng-container>
0
Baruch G. On

The thing is that the type of inner children is ordered (not unordered). So, just change the Recursion Component to :

<ng-container *ngIf="nested.type==='ordered-list-item'">
<li>{{text}}</li>
</ng-container>
2
xyz On

It doesn' t work because you are not having any input property as nested in the recursion component. IMHO, you don't need as many input properties just each Child object will do.

Have something like:

App componenent

<ng-container *ngIf="nested.type==='unordered-list-item'">
    <li>{{nested.text}}</li>
    <ul *ngIf="nested.children.length > 0">
        <app-recursion *ngFor="let child of nested.children" [child]="child"></app-recursion>
    </ul>
</ng-container>

Recursion Component.

<ng-container *ngIf="child?.type==='unordered-list-item'">
  <li>{{child.text}}</li>
  <ng-container *ngIf="child.children?.length > 0">
    <ul>
            <app-recursion *ngFor="let subChild of child.children" [child]="subChild"></app-recursion>
    </ul>
  </ng-container>
</ng-container>

<ng-container *ngIf="child?.type==='ordered-list-item'">
  <li>{{child.text}}</li>
  <ng-container *ngIf="child.children?.length > 0">
    <ol>
            <app-recursion *ngFor="let subChild of child.children" [child]="subChild"></app-recursion>
    </ol>
  </ng-container>
</ng-container>

See an example here: https://stackblitz.com/edit/angular-qzezhp?file=src%2Fapp%2Frecursion%2Frecursion.component.html

EDIT

With the current logic, list type is being decided by the parent, for example, if the last child in the root has type: "ordered-list-item" and its children are of type unordred-list-item then still ordered lists are generated with something like:

<ng-container *ngIf="child?.type==='ordered-list-item'">
  <li>{{child.text}}</li>
  <ng-container *ngIf="child.children?.length > 0">
    <ol>  <-- even though children are un-ordered
            <app-recursion *ngFor="let subChild of child.children" [child]="subChild"></app-recursion>
    </ol>
  </ng-container>
</ng-container>

Solution:

Have another property in each object which tells about the children type, I have named that property as childrenType and used with a dummy data, you will jhave to write your logic to add this property dynamically.

Once this has been done:

You can have something like this in your Recursion component.

  <li>{{child.text}}</li>
    <ng-container *ngIf="child.children?.length > 0">
        <ul *ngIf="child.childrenType==='unordered-list-item'">
            <app-recursion *ngFor="let subChild of child.children" [child]="subChild"></app-recursion>
        </ul>
    <ol *ngIf="child.childrenType==='ordered-list-item'">
      <app-recursion *ngFor="let subChild of child.children" [child]="subChild"></app-recursion>
    </ol>
    </ng-container>

See a revised example here: https://stackblitz.com/edit/angular-list-component-4kmets?file=src/app/app.component.ts

0
StepUp On

Send data into your app-recursion component from nested.children array.

So app.component.html should look like this:

<ng-container *ngIf="nested.type==='unordered-list-item'">
    <li>{{nested.text}}</li>    
    <ul *ngIf="nested.children.length > 0">     
    <app-recursion [children]="nested.children"></app-recursion>
    </ul>
</ng-container>

And then use *ngFor in recursion.component.html:

<ng-container >
  <li *ngFor="let child of children" >
      {{child.text}}
  </li>
</ng-container>