Data Table Pagination using Angular Material

Utkarsh Chakravarty
The Startup
Published in
4 min readJun 7, 2020

--

Explaining how to perform pagination of the data on the HTTP observable stream with the help of Angular Material

There might be a case in which we want to fetch a list of items or data from backend so many of us want to get only that part of data that is to be displayed on the screen in order to increase the performance of your webApp.

This problem can be solved with the help of many npm libraries but here I’ll tell you how to use MatPaginatorModule to handle pagination which is a module provided by Angular Material. So let’s start…

Create a new Project

ng new pagination-test

Install Angular Material

Use the Angular CLI’s install schematic to set up your Angular Material project by running the following command:

ng add @angular/material

API reference for Angular Material paginator

As mentioned earlier, we’ll use the MatPaginatorModule so it has to be imported to the app.module.ts

import {MatPaginatorModule} from '@angular/material/paginator';

Generate a new component

Generate a new component where you want to display your list items using Angular CLI:

ng generate component list

Now we are ready to use the <mat-paginator> to deal with the pagination technique.

<mat-paginator> provides navigation for paged information, typically used with a table.

Now move to list.component.html and use the paginator below the list in the following manner.

<mat-paginator[length]="totalItems"[pageSize]="itemsPerPage"[pageSizeOptions]="[5, 10, 25, 100]"(page)="onPaginate($event)"></mat-paginator>

Each paginator instance requires:

  • The number of items per page (default set to 50)
  • The total number of items being paged

The current page index defaults to 0, but can be explicitly set via pageIndex.

When the user interacts with the paginator, a PageEvent will be fired that can be used to update any associated data view.

Page size options

The paginator displays a dropdown of page sizes for the user to choose from. The options for this dropdown can be set via pageSizeOptions

The current pageSize will always appear in the dropdown, even if it is not included in pageSizeOptions.

Now move to list.component.ts, there we have to handle the event that is fired when the user interacts with the paginator.

export class ItemComponent {constructor(private itemSerivce: ItemService) { }onPaginate(pageEvent: PageEvent) {this.postPerPage = +pageEvent.pageSize;this.pageNumber = +pageEvent.pageIndex + 1;this.itemService.getItems(this.postPerPage, this.pageNumber);
}
}

When the page event is fired up, it provides the updated options that the user has chosen. So accordingly, we will fetch the data from the backend by providing the figures which the user exactly wants.

Here ‘+’ is used to convert the string data to number as otherwise, it will throw an error on assigning a number type variable to string value.

We are using an ItemService class to interact with the backend as it is considered as a good practice to use a separate service class to perform the interaction with the backend server.

Creating a service class

Create a file named item.service.ts adjacent to the item component and write the following code.

import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {map} from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class ItemService {items: any;getItems(pageSize: number, currentPage: number) {const queryParams = `?pageSize=${pageSize}&page=${currentPage}`;return this.http.get<{ message: string, items: any, maxCount: number }>('API_URL' + queryParams).pipe(map((itemData) => {return {item: itemData.items,maxCount: itemData.maxCount};})).subscribe((res) => {this.items = res.item;});
}
}

Bonus: Server-side logic

We are using NodeJs and Express to implement the server endpoint of the pagination operation. In this, we’ll use the ‘skip’ and ‘limit’ option provided by the mongoose query to skip some items and limit the maximum number of items to be sent or received.

const express = require('express');const app = express();const port = process.env.PORT || 3000;app.use(express.json());//get req to fetch the items
app.get(req, res, next) => {
const pageSize = +req.query.pageSize;const currentPage = +req.query.page;let fetchedItems;const itemQuery = Item.find();if (pageSize && currentPage) {itemQuery.skip(pageSize * (currentPage - 1))
.limit(pageSize)
}postQuery.then(items => {fetchedItems = items;Item.count().then((count) => {res.send({message: 'Fetched Successfully',
items: fetchedItems,
maxCount: count
});
});
}).catch(err => {
res.status(500).send({
message: 'Unable to fetch items'
});
});
};
app.listen(port, () => {console.log('Server is up on', port);});

Test your Application

Go to the project folder and launch the server by using the CLI command ng serve and test your work.

ng serve

Thank you for reading!😊

--

--