angularngx-datatable

ngx-data table how to display nested json data in data table in angualr -6


In ngx-data table how to loop through nested Json object in ngx -data table.

json sample object:

rows = [
{ name: 'Austin', gender: 'Male', company: 'Swimlane', topings:[
 { id:'101',name:'spinach'}]
 },
{ name: 'Dany', gender: 'Male', company: 'KFC',topings:[
 { id:'102',name:'onion'}] },
{ name: 'Molly', gender: 'Female', company: 'Burger King' ,topings:[
 { id:'103',name:'ginger'}]},

];

In ngx-datatable how I need to loop through topings in above json object and display toping data in data table. could any one please answer how I have to do it....??


Solution

  • Alright, what I am thinking is that, you will need to do some manipulation on your data before you can render it on your datatable.

    On your component.ts, first, you should define your columns.

    tableColumns = [
      {
        prop: 'name',
        name: 'Name'
      },
      {
        prop: 'gender',
        name: 'Gender'
      },
      {
        prop: 'company',
        name: 'Company'
      },
      {
        prop: 'topingsId',
        name: 'Topings ID'
      }, 
      {
        prop: 'topingsName',
        name: 'Topings Name'
      }
    ]
    

    Next, you should attempt to 'flatten' that your data such that it an array of single-level objects (instead of having them nested).

    this.rows = [
      { 
        name: 'Austin', gender: 'Male', company: 'Swimlane', topings:[{ id:'101',name:'spinach'}]
      },
      { 
        name: 'Dany', gender: 'Male', company: 'KFC',topings:[{ id:'102',name:'onion'}] 
      },
      { 
        name: 'Molly', gender: 'Female', company: 'Burger King' ,topings:[{ id:'103',name:'ginger'}]
      }
    ];
    
    this.rows = this.rows.map(row => ({
      name: row['name'],
      gender: row['gender'],
      company: row['company'],
      topingsId: row['topings'][0]['id'],
      topingsName: row['topings'][0]['name']
    }));
    
    console.log(this.rows);
    

    Last but not least, on your component.html, you can render your datatable as such:

    <ngx-datatable class="material" [rows]="rows" [columns]="tableColumns"....></ngx-datatable>
    

    And don't forget to define the other properties that your table will need.


    Additional ways to assign your row data using some ES6 magic.

    1) Using the Spread Syntax:

    this.rows = this.rows.map(row => ({
      ...row,
      topingsId: row['topings'][0]['id'],
      topingsName: row['topings'][0]['name']
    }));
    

    2) Using both the Spread Syntax and Object Destructuring:

    this.rows = this.rows.map(row => {
      const {topings, ...others} = row;
      return {
        ...others,
        topingsId: row['topings'][0]['id'],
        topingsName: row['topings'][0]['name']
      };
    });
    

    And to answer your question on the comments, our datatable rows and columns are dynamic, we have to adopt a slightly different strategy.

    First, we flatten your data to an array of unnested objects. We get an array of the topings for each row, and then we convert the array into an object. After which, we use the spread synxtax to join everything into one object, which represents a row within this.rows.

    Take note that we are making use of Computed Property Names (yet another ES6 feature) to provide the dynamic property key of each toping.

    this.rows = this.rows.map(row => {
      const {topings, ...others} = row;
      const topingsList = topings.map((toping, index) => ({
        ['toping' + Number(index + 1) + ' Name']: toping['name']
      }));
      topingsObject = Object.assign({}, ...topingsList);
      return { 
        ...others,
        ...topingsObject
      }
    });
    

    Next, from the rows data, we have to gather the array of new columns which is one of the required properties of ngx-datatable. First, our this.tableColumns is defined as such:

    tableColumns = [
      {
        prop: 'name',
        name: 'Name'
      },
      {
        prop: 'gender',
        name: 'Gender'
      },
      {
        prop: 'company',
        name: 'Company'
      }
    ];
    

    And right after we have obtained the flattened this.rows, we will obtain an array of the properties that are available within the row data. From there, we update the tableColumns with the dynamic toppings (eg. Toping1 Name, Toping2 Name, ..etc)

    this.rows = this.rows.map(row => { .....}) // continued from the above
    
    const headerNames = Object.keys(Object.assign({}, ...this.rows));
    headerNames.map(header => {
      if (header!=='name' && header!=='gender' && header!=='company') {
        this.tableColumns.push({
          prop: header,
          name: header
        });
      }
    });