Angular Material Data Table

In this article we'll take a look at implementing a basic data table in angular material. as always the first step is to import the module so in material.module.ts and add it to the MaterialComponents[] array.

import { MatTableModule } from "@angular/material/badge";

const MaterialComponents = [
  MatTableModule,
]

Now to save some time for us let's copy the code for a basic data table and then understand the different parts that are responsible for the functioning of a data table so in the material docs go to components and then to the data table section and click on the table link over there in the examples tab we have a basic data table go to the second example which is a basic use of <mat-table> and uses display: flex and click on the code icon. angular material data table

Let's copy that HTML code first and paste it in the app.component.html.

<mat-table [dataSource]="dataSource" class="mat-elevation-z8">
  <!-- Position Column -->
  <ng-container matColumnDef="position">
    <mat-header-cell *matHeaderCellDef> No. </mat-header-cell>
    <mat-cell *matCellDef="let element"> {{element.position}} </mat-cell>
  </ng-container>

  <!-- Name Column -->
  <ng-container matColumnDef="name">
    <mat-header-cell *matHeaderCellDef> Name </mat-header-cell>
    <mat-cell *matCellDef="let element"> {{element.name}} </mat-cell>
  </ng-container>

  <!-- Weight Column -->
  <ng-container matColumnDef="weight">
    <mat-header-cell *matHeaderCellDef> Weight </mat-header-cell>
    <mat-cell *matCellDef="let element"> {{element.weight}} </mat-cell>
  </ng-container>

  <!-- Symbol Column -->
  <ng-container matColumnDef="symbol">
    <mat-header-cell *matHeaderCellDef> Symbol </mat-header-cell>
    <mat-cell *matCellDef="let element"> {{element.symbol}} </mat-cell>
  </ng-container>

  <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
  <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>

Next let's open the typscript tab, so go to TS copy the code and paste it in app.component.ts here is the complete code for now.

import { Component, OnInit } from "@angular/core";

export interface PeriodicElement {
  name: string;
  position: number;
  weight: number;
  symbol: string;
}

const ELEMENT_DATA: PeriodicElement[] = [
  { position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H' },
  { position: 2, name: 'Helium', weight: 4.0026, symbol: 'He' },
  { position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li' },
  { position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be' },
  { position: 5, name: 'Boron', weight: 10.811, symbol: 'B' },
  { position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C' },
  { position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N' },
  { position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O' },
  { position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F' },
  { position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne' },
];

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.scss"]
})
export class AppComponent {
  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
  dataSource = ELEMENT_DATA;
}

Finally copy the CSS and paste it in app.component.scss.

table {
  width: 100%;
}

If we save all the files and take a look at the browser you should be able to see a data table, angular material data table preview

Now let's understand the different parts that make up this data table.

The first part to implementing a data table is the data source, every data table needs a data source that contains the data to be displayed in our example we have the data of Periodic Elements we have an Interface that defines the type of each element so a periodic element will have a name, position, weight and symbol. right below the interface is where you see the array of periodic elements we have 10 elements each having properties mentioned in the interface what you have to notice here is that the interface and the data array is declared outside the component to be able to use it in the component we need to create property and initialize it for that purpose we have data source which is initialized to ELEMENT_DATA.

The second part is to provide this data source to the data table and we do that in the HTML so in app.component.html we create a data table with <mat-table> component and to provide tha data source we use of the dataSource attribute we use property binding to bind the property defined in the component class so that is the first step to implementing a data table, creating the dataSource and binding it to the table. The next step is to define the column templates in the browser, you can see that we have 4 columns: position number, name, weight and symbol, in the code we define the four columns each inside it's own <ng-container> element this element will not be rendered to the Dom but it will provide and element for applying this matColumnDef directive which is what uniquely identifies a given column with key (position, name, weight, symbol) within the <ng-container> element we'll have all the configuration for a given column you can see that we have the template that defines how to display the header for a given column using *matHeaderCellDef structural directive, we also have another template that defines how to display the data cells for given column using *matCellDef structural directive the two structural directives do not attach any styling to the elements the styling is taken care of by <mat-header-cell> and <mat-cell> components. Next let's talk about the content of heading and the data cells for the heading you can see that we just have static text (No. , Name, Weight, Symbol) but for the data cell we get access to each row of the dataSource we obtain a reference to each row the then access the different properties of each row we then use interpolation to bind the data to the view so in our dataSource we have 10 rows we iterate through the rows get a reference to each row and store it in the element variable and then we access appropriate property in the column template, alright what we have done so far is just define the column template how it supposed to look.

The final step to define the rows in the data table and for that we make use of two more components, to define the table header row we make use of the <mat-header-row> component and to determine which columns have to be displayed in the table using *matHeaderRowDef structural directive to this we assign displayedColumns property which is an array of columns we have mentioned in the component class which is an array of strings with position, name, weight, symbol. Similarly to display the data rows we make use of the <mat-row> component with *matRowDef structural directive we also have a variable exported that we have named as row containing the data of that given row and we have to specify columns property which contains the order in which the data cells should be rendered.

So we run this code we should have the data table working as expected. angular material data table rendering

To summarize there are three steps in implementing a data table in angular material.

  1. First Step: define the dataSource and the columns to be displayed.
  2. Second Step: define the column templates.
  3. Third Step: include the header and the row definitions.

So we are able to create a very basic data table we copy pasted the code and did not really code anything as such so in the next lecture let's also try to make some changes and see how that impacts the data table, that will give you a much better understanding of how the data table works.