11

I am having a problem creating tables dynamically with Angular Material tables. As the table depends on an interface, I have a fixed number of columns. What I want is to have a dynamic table depending on response from the server. Is there any way to dynamically create the interface or something? Because the way the application is designed is sometimes there would be 2 columns and some times 3 and so on depending on the size of the array. My interface currently looks like

export interface Data{
    file:any,
    typea:any,
    typeb:any
}

With this interface I have 3 columns. There are minimum 3 columns but depending on data there could be more than 3. I am not able to achieve this, any help would be appreciated.

1

2 Answers 2

24

The easiest way to do this is to include all possible columns in an array (definedColumns), and iterate over it for the header & cell definitions.

Then for the columns you want to show conditionally, you can control which are displayed by having a separate array that contains a string list of the columns you want to actually show (columnsToDisplay). Simply adding and removing columnIds from this list will result in the table updating with the appropriate columns.

<table mat-table [dataSource]="data" class="mat-elevation-z8">
  <ng-container matColumnDef="{{column}}" *ngFor="let column of definedColumns">
    <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>

There's a live example of this given on the angular material website, see "Table dynamically changing the columns displayed " on their examples page here - https://material.angular.io/components/table/examples


Note: For more advanced examples, like if you needed to pass a TemplateRef for your cell and header definitions, you'll probably want to check out Angular Material's CDK.

You can dynamically add and remove columns from the table using Angular's CDK API. If you add #table to your mat-table element then you can have your component use it as a @ViewChild. Then you can use this.table.addColumnDef and pass your new column. See https://material.angular.io/cdk/table/api#CdkColumnDef for more details.

Sign up to request clarification or add additional context in comments.

Comments

1

I'm not 100% down with angular-material tables, but this would allow you to create dynamic properties on your Data object after a server call.

This is a javascript example which will be interchangeable with your typescript implementation where the promise is your http call.

var obj = { };
var promise = new Promise(resolve => resolve(['one', 'two', 'three']));

promise.then(data => {
  for (let column of data){
    obj[column] = 'data -> ' + column;
  }
  
  console.log(obj);
});

1 Comment

How are you associating the values to the interface? Is there a way of using mat tables without an interface?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.