Reputation: 3526
I have below json and want to render in material table in angular
var res = '[
{
"DynamicName": "xyz",
"DynamicLevel": "xyz",
"DynamicLevel": "xyz",
"DynamicLevel": "xyz",
"dynamic": "xyz"
},
{
"DynamicName": "xyz",
"DynamicLevel": "xyz",
"DynamicLevel": "xyz",
"DynamicLevel": "xyz",
"dynamic": "xyz"
},
{
"DynamicName": "xyz",
"DynamicLevel": "xyz",
"DynamicLevel": "xyz",
"DynamicLevel": "xyz",
"dynamic": "xyz"
}]';
In second response this json will be like below
var res = '[
{
"DynamicCity": "xyz",
"DynamicCountry": "xyz",
"DynamicState": "xyz",
"DynamicRegion": "xyz",
"dynamic": "xyz"
},
{
"DynamicCity": "xyz",
"DynamicCountry": "xyz",
"DynamicState": "xyz",
"DynamicRegion": "xyz",
"dynamic": "xyz"
},
{
"DynamicCity": "xyz",
"DynamicCountry": "xyz",
"DynamicState": "xyz",
"DynamicRegion": "xyz",
"dynamic": "xyz"
}]';
this data need to render in material table I have tried like this
// properties of the class
displayedColumns: string[];//columns should be create dynamically
dataSource = res;
<table mat-table [dataSource]="dataSource | keyvalue" class="mat-elevation-z8">
<ng-container matColumnDef="key">
<th mat-header-cell *matHeaderCellDef> {{element.key}}</th>
<td mat-cell *matCellDef="let element"> {{element.value}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
I need output like below
Here, dynamic column means in each api call we get different data for this column names so it will be changed every api call so I am not able to bind it to material table. Please help me to solve this issue of binding json data to material table. reference URLs:-
Upvotes: 2
Views: 4851
Reputation: 11
https://material.angular.io/components/table/examples :
<table mat-table [dataSource]="data" class="mat-elevation-z8">
<ng-container [matColumnDef]="column" *ngFor="let column of
displayedColumns">
<th mat-header-cell *matHeaderCellDef> {{column}} </th>
<td mat-cell *matCellDef="let element"> {{element[column]}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
<tr mat-row *matRowDef="let row; columns: columnsToDisplay;"></tr>
</table>
Upvotes: 1
Reputation: 26
import { Component,OnInit } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.sass']
})
export class AppComponent implements OnInit {
title = 'jsonDemo';
ELEMENT_DATA1 = [
{ 'DynamiCCity': 'Hydrogen' , 'DynamicCountry' : 'Country', 'DynamicState' : 'State' , 'DynamicRegion' :'DynamicRegion' , 'dynamic' :'dynamic' },
{ 'DynamiCCity': 'Hydrogen 1' , 'DynamicCountry' : 'Country 1', 'DynamicState' : 'State 1' , 'DynamicRegion' :'DynamicRegion 1' , 'dynamic':'dynamic 1' },
];
displayedColumns: string[] = [];
dataSource1 = this.ELEMENT_DATA1;
ngOnInit(): void
{
this.displayedColumns = Object.getOwnPropertyNames(this.ELEMENT_DATA1[0]);
}
}
<h2>Demo</h2>
<style>
table {
width: 100%;
}
</style>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<ng-container *ngFor="let item of displayedColumns" matColumnDef="{{item}}">
<th mat-header-cell *matHeaderCellDef> {{item}} </th>
<td mat-cell *matCellDef="let element"> {{ element[item] }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<router-outlet></router-outlet>
I Hope Above Code is Working Demo of your Issue. It will work as expected.
Upvotes: 1
Reputation: 876
I created a Stackblitz for you. This should work with any lists with objects with simple values (will take the keys from the first object, so all the objects needs to be the same for the current list (no way around this without creating separate tables)): https://stackblitz.com/edit/angular-pqgny8?file=src/app/table-basic-example.html
HTML:
<table *ngIf="dataSource && displayedColumns" mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<ng-container *ngFor="let k of displayedColumns">
<ng-container [matColumnDef]="k">
<th mat-header-cell *matHeaderCellDef> {{k}}</th>
<td mat-cell *matCellDef="let element"> {{element[k]}} </td>
</ng-container>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
TS:
getData() {
this.dataSource = ELEMENT_DATA; // ELEMENT_DATA is the data from your backend
this.displayedColumns = Object.keys(this.dataSource[0]).map(k => k)
}
Upvotes: 2
Reputation: 1898
Html
<div class="demo-button-container">
<button mat-raised-button (click)="addData()" class="demo-button">
Add data
</button>
<button
mat-raised-button
[disabled]="!dataSource.length"
(click)="removeData()"
class="demo-button">
Remove data
</button>
</div>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8 demo-table">
<!-- Position Column -->
<ng-container [matColumnDef]="col" *ngFor="let col of displayedColumns">
<th mat-header-cell *matHeaderCellDef>
{{col}}
</th>
<td mat-cell *matCellDef="let element">
{{element[col]}}
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
ts
import {Component, ViewChild} from '@angular/core';
import {MatTable} from '@angular/material/table';
export interface dynElement {
DynamicName: string,
DynamicLevel_1: string,
DynamicLevel_2:string,
DynamicLevel_3:string,
dynamic:string
}
const ELEMENT_DATA: any [] = [
{
DynamicName: "xyz",
DynamicLevel_1: "xyz",
DynamicLevel_2: "xyz",
DynamicLevel_3: "xyz",
dynamic: "xyz"
},
{
DynamicName: "xyz",
DynamicLevel_1: "xyz",
DynamicLevel_2: "xyz",
DynamicLevel_3: "xyz",
dynamic: "xyz"
},
{
DynamicName: "xyz",
DynamicLevel_1: "xyz",
DynamicLevel_2: "xyz",
DynamicLevel_3: "xyz",
dynamic: "xyz"
},
{
DynamicName: "xyz",
DynamicLevel_1: "xyz",
DynamicLevel_2: "xyz",
DynamicLevel_3: "xyz",
dynamic: "xyz"
},
]
@Component({
selector: 'table-dynamic-array-data-example',
styleUrls: ['table-dynamic-array-data-example.css'],
templateUrl: 'table-dynamic-array-data-example.html',
})
export class TableDynamicArrayDataExample {
// your Object Key Object.keys(obj)
displayedColumns: string[] = [...Object.keys(ELEMENT_DATA[0])];
dataSource = [...ELEMENT_DATA]; // you can pass your data from backend here
@ViewChild(MatTable) table: MatTable<any>;
addData() {
const randomElementIndex = Math.floor(Math.random() * ELEMENT_DATA.length);
this.dataSource.push(ELEMENT_DATA[randomElementIndex]);
this.table.renderRows();
}
removeData() {
this.dataSource.pop();
this.table.renderRows();
}
}
demo in stackblitz
Upvotes: 1