how to use flat data source with Angular Material mat-tree?

Viewed 520

I already have a flat data source, meaning I have columns like "content_Id" and "content_Owner" where 0 is root, else is below that content_Id, how can I implement the mat tree component with my data that is already flat??

I found on the web this solution but it fails a little bit, it doesnt take all my data for the tree, I can't see what's wrong

import { Component, OnInit } from '@angular/core';
import { FlatTreeControl } from '@angular/cdk/tree';
import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree';

interface FoodNodeFlat {
  name: string;
  Id: Number;
  parentId: Number;
  children?: FoodNodeFlat[];
}

interface ExampleFlatNode {
  expandable: boolean;
  name: string;
  level: number;
}

let TREE_DATA: FoodNodeFlat[] = [

  { name: '1. TITLE', Id: 101, parentId: 0 },
  { name: 'sub', Id: 132, parentId: 129 },
  { name: '5.5.1 sub', Id: 138, parentId: 137 },
  { name: '4.1.1 sub', Id: 144, parentId: 108 },
  { name: '2. TITLE', Id: 102, parentId: 0 },
  { name: '4.1 sub', Id: 108, parentId: 106 },
  { name: '5.6. sub ', Id: 133, parentId: 129 },
  { name: '5.5.2 sub', Id: 139, parentId: 137 },
  { name: '3. TITLE', Id: 103, parentId: 0 },
  { name: '5.6.1 sub', Id: 134, parentId: 129 },
  { name: '5.5.3 sub', Id: 140, parentId: 137 },
  { name: '4. TITLE', Id: 106, parentId: 0 },
  { name: '4.2 sub', Id: 110, parentId: 106 },
  { name: '5.7 sub', Id: 135, parentId: 129 },
  { name: '5. TITLE', Id: 129, parentId: 0 },
  { name: '5.4 sub', Id: 136, parentId: 129 },
  { name: '6. TITLE', Id: 131, parentId: 0 },
  { name: '5.5 sub', Id: 137, parentId: 129 },
  { name: '5.6 sub', Id: 141, parentId: 129 },
  { name: '7. TITLE', Id: 142, parentId: 0 },
  { name: '8. TITLE', Id: 143, parentId: 0 },
  { name: '9. TITLE', Id: 145, parentId: 0 },
  { name: '10. TITLE', Id: 146, parentId: 0 }
];
@Component({
  selector: 'app-tree-demo',
  templateUrl: './tree-demo.component.html',
  styleUrls: ['./tree-demo.component.css']
})
export class TREEDEMOComponent implements OnInit {

  private _transformer = (node: FoodNodeFlat, level: number) => {
    return {
      expandable: !!node.children && node.children.length > 0,
      name: node.name,
      level: level,
    };
  }

  treeControl = new FlatTreeControl<ExampleFlatNode>(
    node => node.level, node => node.expandable);
  treeFlattener = new MatTreeFlattener(
    this._transformer, node => node.level, node => node.expandable, node => node.children);
  dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
  constructor() {
    //this.dataSource.data = TREE_DATA;

  }
  hasChild = (_: number, node: ExampleFlatNode) => node.expandable;
  ngOnInit() {
    //this.dataSource.data = TREE_DATA;
    this.dataSource.data = this.treeConstruct(TREE_DATA);
  }

  treeConstruct(treeData) {
    let constructedTree = [];
    for (let i of treeData) {
      let treeObj = i;
      let assigned = false;
      this.constructTree(constructedTree, treeObj, assigned)
    }
    return constructedTree;
  }
  constructTree(constructedTree, treeObj, assigned) {
    if (treeObj.parentId == 0) {
      treeObj.children = [];
      constructedTree.push(treeObj);
      return true;
    } else if (treeObj.parentId == constructedTree.Id) {
      treeObj.children = [];
      constructedTree.children.push(treeObj);
      return true;
    }
    else {
      if (constructedTree.children != undefined) {
        for (let index = 0; index < constructedTree.children.length; index++) {
          let constructedObj = constructedTree.children[index];
          if (assigned == false) {
            assigned = this.constructTree(constructedObj, treeObj, assigned);
          }
        }
      } else {
        for (let index = 0; index < constructedTree.length; index++) {
          let constructedObj = constructedTree[index];
          if (assigned == false) {
            assigned = this.constructTree(constructedObj, treeObj, assigned);
          }
        }
      }
      return false;
    }
  }

}

enter image description here

and my HTML as below

<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
  <!-- This is the tree node template for leaf nodes -->
  <mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding>
    <!-- use a disabled button to provide padding for tree leaf -->
    <button mat-icon-button disabled></button>
    {{node.name}}
  </mat-tree-node>
  <!-- This is the tree node template for expandable nodes -->
  <mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding>
    <button mat-icon-button matTreeNodeToggle [attr.aria-label]="'toggle ' + node.name">
      <mat-icon class="mat-icon-rtl-mirror">
        {{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
      </mat-icon>
    </button>
    {{node.name}}
  </mat-tree-node>
</mat-tree>
0 Answers
Related