0

Goal:

-------------------
|     | foo | haz |
-------------------
| bar | 5   | 7   |
| can | 6   | 8   |
-------------------

It seems like a trivial thing to want… but at second glance it seems quite complicated with all the explicit required:

<ng-container matColumnDef="score">
    <th mat-header-cell *matHeaderCellDef> Score </th>
    <td mat-cell *matCellDef="let user"> {{user.score}} </td>
</ng-container>

What am I missing here, is there not some simple way of construct a material table from that input?

A T
  • 13,008
  • 21
  • 97
  • 158
  • Can you be more specific, what exactly are you trying to achieve? – Richard Schibly Jun 04 '20 at 02:20
  • I am trying to generate a mat-table from this simple nested object. – A T Jun 04 '20 at 02:27
  • There is a fully functioning example of using a simple input object array like that in the web documentation. Have you reviewed that yet? https://material.angular.io/components/table/overview – Richard Schibly Jun 04 '20 at 02:40
  • There are no arrays in my examples… and the headers and column headers aren't known ahead of time. – A T Jun 04 '20 at 02:49
  • There is no simple way to construct the table from that input. You would need to parse out the column names with Object.keys(tableObj), then you would need to construct an object for each row and add it to an array. I suppose I could try to throw an example together for you, are you sure you can't structure your table data in a better way? – Richard Schibly Jun 04 '20 at 03:21

2 Answers2

1

This can be done using Object.keys() and Object.reduce() through below code.

private baseData = {
  foo: {bar: 5, can: 6}, 
  haz: {bar: 7, can: 8}
};

columnNames: string[]; 
data: any[];  

ngOnInit() {
  this.columnNames = [' '].concat(Object.keys(this.baseData));
  const objects = Object.keys(this.baseData).map(key => this.baseData[key]);
  this.data = Object.keys(objects[0]).reduce((acc, k) => {
    const entry = { ' ' : k };
    objects.forEach((o, i) => entry[this.columnNames[i + 1]] = o[k]);
    acc.push(entry);
    return acc;
  }, []);    
}

Please have a look at the following StackBlitz.

uminder
  • 23,831
  • 5
  • 37
  • 72
0

Here is a modified stackblitz of the basic example for mat-table:

https://stackblitz.com/edit/angular-cj5c3w

You cannot get around using an array for the data source on a mat-table, but this should do what you wanted. You'll have to check for side effects and edge cases.

Richard Schibly
  • 437
  • 2
  • 7