Angular Reusable Table component using Angular Material

Angular Reusable Table component using Angular Material

Hello everyone!

This article will straightforward you to create a reusable component for MatTable.

MatTable provide us a data-table, that can be used to display rows. It seems OK, however it is NOT reusable and implies in lots of duplication codes.

For this component, we will use Angular v11.2.6 and Angular Material v11.2.13.

Let's Code! :)

Column Interface

First of all we have to create an interface for Columns.

export interface TableColumn {
  caption: string;
  field: string;
}
        

Table

Now we have to create a reusable table component (command below):

ng generate component table        

This table component will input some data from the parent component.

  • columns: based on TableColumn interface;
  • dataSource: This data has a connection with field from TableColumn interface.

HTML template

<table mat-table [dataSource]="_dataSource">
  <ng-container *ngFor="let c of columns" [matColumnDef]="c.caption">
    <ng-container>
      <th mat-header-cell *matHeaderCellDef>
        {{c.caption}}
      </th>
    </ng-container>
    <td mat-cell *matCellDef="let element">
      {{element[c.field]}}
    </td>
  </ng-container>
  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>        

TypeScript

import { Component, Input, OnInit } from '@angular/core';
import { TableColumn } from "./table.column";
import { MatTableDataSource } from "@angular/material/table";
@Component({
  selector: 'app-table',
  templateUrl: './table.component.html',
  styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit {


  public _dataSource = new MatTableDataSource([]);
  public displayedColumns: string[];
  @Input() columns: TableColumn[];


  @Input() set dataSource(data: any[]) {
    this.setDataSource(data);
  }


  ngOnInit(): void {
    this.displayedColumns = this.columns.map((tableColumn: TableColumn) => tableColumn.caption);
  }


  setDataSource(data: any) {
    this._dataSource = new MatTableDataSource<any>(data);
  }
}

        

After that, we are able to use this component on app.component

app.component.html

<app-table>
  [dataSource]="myData"
  [columns]="myColumns">
</app-table>        

app.component.ts

 

  myData: any
  myColumns: any;


  ngOnInit(): void {
    this.myData = this.getDataSource();
    this.myColumns = this.getColumns();
  }


  getDataSource(): any[] {
    return [
      { name: 'Felipe', mail: 'felipe@gmai.com' },
      { name: 'Cecilia', mail: 'cecilia@gmail.com' }
    ];
  }


  getColumns():  any[] {
    return [
      { caption: 'Name', field: 'name' },
      { caption: 'Mail', field: 'mail' }
    ];
  };        
No alt text provided for this image

Then you are able to use this component. This is a simple example. In the next article, I will implement sort and pagination features.

Source code is available here:

Thanks for reading!

Straight forward indeed, how would one add buttons like delete or edit?

Like
Reply

To view or add a comment, sign in

More articles by Felipe Borella

Others also viewed

Explore content categories