Ad

Parsing Categories Tree Into HTML Select Tag

I have this categories tree input :

"categories": [
    {
        "text": "Upstate",
        "id": 3,
        "category_parent_id": 0,
        "children": []
    },
    {
        "text": "North",
        "id": 2,
        "category_parent_id": 0,
        "children": [
            {
                "text": "Child N 1",
                "id": 5,
                "category_parent_id": 2,
                "children": [
                    {
                        "text": "Another Child 1",
                        "id": 11,
                        "category_parent_id": 5,
                        "children": []
                    },
                    {
                        "text": "Another Child 2",
                        "id": 10,
                        "category_parent_id": 5,
                        "children": []
                    }
                ]
            },
            {
                "text": "Activity",
                "id": 4,
                "category_parent_id": 2,
                "children": []
            }
        ]
    },
    {
        "text": "Health",
        "id": 1,
        "category_parent_id": 0,
        "children": [
            {
                "text": "Good Health",
                "id": 9,
                "category_parent_id": 1,
                "children": []
            },
            {
                "text": "Bad Health",
                "id": 8,
                "category_parent_id": 1,
                "children": []
            }
        ]
    }
]

So, now I want to populate my select box like this :

Upstate

North

-Child N 1

--Another Child 1

--Another Child 2

-Activity

Health

-Good Health

-Bad Health

So, how can I parse through the input tree and populate the select box with these values? Any algorithm or recursive function approach I can use to achieve this ?

Ad

Answer

make a recursive function

  flatCategories(data: any[], children: any[], index: number) {
    data=data||[];
    children.forEach(x => {
      data.push({ id: x.id, text: '-'.repeat(index) + x.text });
      if (x.children && x.children.length)
        this.flatCategories(data, x.children, index + 1)
    })
    return data
  }

You can use like

let dataFlat=this.flatCategories([], this.data.categories, 0);
console.log(this.dataflat.map(x => x.text))

If you want to create a recursive component it's easy (but in case of select not work)

@Component({
  selector: 'item-line',
  template: `
       <div *ngFor="let item of children" [style.margin-left]="index+'rem'">
            {{item.text}}
            <item-line *ngIf="item.children" [children]="item.children" [index]="index+1">
            </item-line>
         </div> 

  `,
})
export class HelloComponent  {
 @Input() children:any[]
 @Input() index:number=0;
}

You can see in stackblitz

Ad
source: stackoverflow.com
Ad