Building a data-table & retrieving data through HTTP with Angular Material | Part 1

India Evans
Oct 16, 2018 · 6 min read

Introduction

Angular Material is a project by the Angular team that provides high-quality UI components based on Google’s Material Design specification.

In this tutorial, we will build a Material Design styled data-table with pagination and sorting. This table builds on the foundation of the CDK data-table.

The cdk-table is a customizable table component in the Angular CDK (Component Dev Kit). It allows developers to have full control over styling and interaction patterns associated with the table. Read more about the Angular CDK here.

In this tutorial you will learn how to

Part 1:

  • Get started with Angular Material
  • Mock a REST API using JSON Server and faker.js
  • Set up a data-table using Angular Material’s mat-table component

Part 2:

  • Create a service to retrieve data through HTTP
  • Create a custom Material CDK Data Source
  • Add pagination to the table
  • Add sorting to the table

The complete code can be found here.

Before we get started…

You will need a data source. I am using JSON Server and faker.js to create a backend of fake products. You can use any API you prefer, but keep in mind that it must be able to handle requests that involve pagination and sorting if you want that in your table.

You will need an Angular 6 app. Don’t have one? Use the Angular CLI!

npm install -g @angular/cli
ng new example-material-app
cd example-material-app
npm install
ng serve

Tutorial

Get started with Angular Material

To start using Angular Material, we need get a few dependencies and make the necessary config changes — the fastest way to do this is with the Angular CLI:

ng add @angular/material

This will update your Angular project with the correct dependencies, perform configuration changes, and execute initialization code, meaning less set-up for us, yay!

Running ng add will:

Manual setup for Angular Material

If for some you reason you want to do it all manually, you can also use npm:

npm install --save @angular/material @angular/cdk @angular/animations

With this approach, you will need to manually import BrowserAnimationsModule into your application to enable animations support.

import Browser Animations module in app.module.ts

And import a theme to apply Material’s core styles and theme styles to your components:

import an Angular Material pre-built theme in angular.json

Here are the currently available pre-built themes:

  • deeppurple-amber.css
  • indigo-pink.css
  • pink-bluegrey.css
  • purple-green.css

Angular Material Typography

By default, Angular Material does not apply any global CSS. To enable Angular Material typography on everything, you can add the mat-typography class to the body tag in index.html:

<body class="mat-typography">  <app-root></app-root></body>

Import the Angular Material components

Now we will go ahead and create a separate NgModule, where we will import all of the Angular Material components we want to use in our application. This will keep us from cluttering up the root module.

ng generate module my-material --flat -m app

Note: The --flat flag prevent an additional directory being created for my-material.module.ts. -m (alias for --module) will automatically import it into app.module.ts.

MyMaterialModule should be imported in root module

In MyMaterialModule, we will import the NgModule for each Angular Material component we want to use. To build a data-table, we of course will need mat-table, as well as mat-paginator and mat-sort-header to add pagination and sorting later.

import { MatTableModule } from '@angular/material/table';import { MatPaginatorModule } from '@angular/material/paginator';import { MatSortModule } from '@angular/material/sort';

Be sure to add the modules to the imports as well as the exports array in MyMaterialModule:

@NgModule({imports: [  CommonModule,  MatTableModule,  MatPaginatorModule,  MatSortModule],declarations: [],exports: [  MatTableModule,  MatPaginatorModule,  MatSortModule]})export class MyMaterialModule { }

Set up fake REST service to provide data

Install JSON Server and faker (-D adds them to your devDependencies):

npm install -D json-server faker

Then create the schema file:

touch db.json

Inside db.json, we can either add our own data manually, or use a random JSON generator — this is where faker comes in. To use faker, first create a JavaScript file:

touch generateFakeData.js

In generateFakeData.js add the following to create 100 fake products:

var faker = require('faker');var database = { products: [] };for (let i=1; i<=100; i++) {
database.products.push({
id: i,
name: faker.commerce.productName(),
price: faker.commerce.price(),
rating: Math.floor(Math.random() * 5 + 1)
});
}
console.log(JSON.stringify(database));

Now output this data to db.json:

node generateFakeData.js > db.json

We now have a large amount of fake data we can use to display in the table. Run json-server so that we can access the API endpoints:

json-server db.json

Note: If you’d like, you can you can run run the JSON server with npm run json-server by adding a command to the scripts section of package.json:

"json-server": "json-server --watch db.json --port 3000"

Test that it’s working as expected by sending a GET request with Postman:

Create a component for the table

Now that we have everything we need to start working with Angular Material components, and we have our data source ready, let’s create a table.

Create a new component using the CLI:

ng g component my-table

In my-table’s html template we will add the mat-table component:

<table mat-table
[dataSource]="fakeProducts"
class="mat-elevation-z2">

...continued below
</table>

The table receives the data that it displays through the dataSource input. Later in the tutorial, we will implement a custom Observable-based Angular CDK Data Source to feed data to the table.

Define the column templates

Inside the table element we will add ng-container elements for each column in the table. These can be in any order, as the actual rendered columns will be set as a property on the row definition.

Each column definition needs a unique name and should contain the content for its header and row cells. The example below shows a column for product name:

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

Define the row templates

Now we need to tell the table which columns to render in the header and data rows. First, create a variable in your component.ts that contains the list of the columns you want to render.

displayedColumns = ['id', 'name', 'price', 'rating'];

Then add mat-header-row and mat-row to the content of your mat-table and provide your column list as inputs.

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

Connect to the data source

Coming soon in Part 2!

India Evans

Written by

I am a web developer in Durham, NC with a passion for front-end development.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade