Search code examples
angularfilterdropdown

Angular showing both main and sub category in one dropdown list


I have an array and need them to be present in dropdown list using Angular where both main and sub departments need to be in the same dropdown list that not all the main department has a sub department. the following is the one I would like to achieve as output dropdown list

  • Human Resource
  • IT - repair
  • IT- analysis
  • Account
departments=[
{id:"1",Category:"Human Resource", ChildOf: "0", Name: "Human Resource"},
{id:"2",Category:"IT", ChildOf: "0", Name: "IT"},
{id:"3",Category:"Account", ChildOf: "0", Name: "Account"},
{id:"4",Category:null, ChildOf: "2", Name: "Analysis"},
{id:"5",Category:null, ChildOf: "2", Name: "Repair"}
]

I am not sure how i can achieve this. Is it i need to use filter function or it can be done with ngIf and ngFor or a combination of both? any help would be great. Thank you so much


Solution

  • If you can, I would go to the source of that data and restructure it, because that is a horrendous way to organize data. Something like this:

      departments = [
        { id: '1', category: 'Human Resource', children: [] },
        {
          id: '2',
          category: 'IT',
          children: [
            { id: '4', name: 'Analysis' },
            { id: '5', name: 'Repair' },
          ],
        },
        { id: '3', category: 'Account', children: [] },
      ];
    

    Then the html is like this:

    <select>
      <ng-container *ngFor="let d of departments">
        <ng-container *ngIf="d.children.length === 0">
          <option>{{ d.category }}</option>
        </ng-container>
        <ng-container *ngIf="d.children.length > 0">
          <option *ngFor="let c of d.children">
            {{ d.category }} - {{ c.name }}
          </option>
        </ng-container>
      </ng-container>
    </select>
    

    If you can't restructure it from the source then you can convert it before serving it to the html:

      badData = [
        { id: '1', Category: 'Human Resource', ChildOf: '0', Name: 'Human Resource' },
        { id: '2', Category: 'IT', ChildOf: '0', Name: 'IT' },
        { id: '3', Category: 'Account', ChildOf: '0', Name: 'Account' },
        { id: '4', Category: null, ChildOf: '2', Name: 'Analysis' },
        { id: '5', Category: null, ChildOf: '2', Name: 'Repair' },
      ];
    
      departments: {
        id: string;
        category: string;
        children: { id: string; name: string }[];
      }[] = [];
    
      ngOnInit() {
        for (const d of this.badData) {
          if (d.Category && d.ChildOf === '0')
            this.departments.push({ id: d.id, category: d.Category, children: [] });
        }
        for (const d of this.badData) {
          if (d.ChildOf !== '0') {
            const parent = this.departments.find((el) => el.id === d.ChildOf);
            if (parent) parent.children.push({ id: d.id, name: d.Name });
          }
        }
      }