4

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....??

4
  • hi, what are the header names/properties that you want to use on your datatable? Commented Mar 22, 2019 at 1:27
  • Also, are you trying to display everything on a row, or are you planning to use row-details to display the nested topings Commented Mar 22, 2019 at 1:38
  • I want to display every thing in a row not in row detail. I Want to display name|gender|company|topings.name ...like this I want to display using ngx datatable. usually for normal table I use ngFor to iterate through objects.objetcs. but in ngx data table how I need to do....? Commented Mar 22, 2019 at 13:42
  • Ok, I have produced my answer. It should work, as this is what I have always been doing when i use ngx-datatable. Commented Mar 22, 2019 at 14:34

2 Answers 2

7

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
    });
  }
});
Sign up to request clarification or add additional context in comments.

9 Comments

Thanks @wentjun , I wil try and let you know . Thank you so much for your response
this.rows = [ { name: 'Austin', gender: 'Male', company: 'Swimlane', topings:[{ id:'101',name:'spinach'},{id:'110',name:'pineapple'}] }, { name: 'Dany', gender: 'Male', company: 'KFC',topings:[{ id:'102',name:'onion'}] }, { name: 'Molly', gender: 'Female', company: 'Burger King' ,topings:[{ id:'103',name:'ginger'}] } ]; suppose one row has multiple toppings we need to store it in array of toppings in row. how we do. In above ode we are taking only zeroth index[0] .
and above code is working perfectly for zeroth topping , Thanks @wentjun
Hmmm, do you want to store the all of the toppings in the same column for each row? Or do you want to store each topping object in a different column?
This answer was super helpful. This is definitely a way for dynamic table rows.
|
2

Well I think there is a simpler way and yes it's very simple. Just do the following:

Let's imagine you have a nested json object like this:

    data = {
        "id": 1,
        "name": "John Doe"
        "comments": [
            {"id":1, "content": "Some content" },
            {"id":2, "content": "Some content" }
        ]
    };

In your HTML template:

<ngx-datatable-column name="Comment" prop="comments">
    <ng-template let-value="value" ngx-datatable-cell-template>
        <span>{{value.content}}</span>
    </ng-template>  
</ngx-datatable-column>

2 Comments

Typo: third line should be close tag </ng-template>. Thank you for anser
fixed. Thumbs up !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.