Angular 13 Pagination example (server side) with ngx-pagination

In this tutorial, I will show you how to make Angular 13 Pagination example with existing API (server-side pagination) using ngx-pagination.

Other versions:
Angular 8 Pagination example | ngx-pagination
Angular 10 Pagination example | ngx-pagination
Angular 11 Pagination example | ngx-pagination
Angular 12 Pagination example | ngx-pagination
Angular 14 Pagination example | ngx-pagination
Angular 15 Pagination example | ngx-pagination

Related Posts:
Angular CRUD Application with Rest Api
Angular Form Validation example (Reactive Forms)
Angular File upload example with Progress bar
Angular JWT Authentication example with Web Api

Fullstack with Node.js Express:
Server side Pagination with Node.js and Angular

Fullstack with Spring Boot:
Spring Boot + Angular: Server side Pagination example


Overview of Angular 13 Pagination example

One of the most important things to make a website friendly is the response time, and pagination comes for this reason. For example, this bezkoder.com website has hundreds of tutorials, and we don’t want to see all of them at once. Paging means displaying a small number of all, by a page.

Assume that we have tutorials table in database like this:

angular-13-pagination-example-ngx-pagination-database

Our Angular 13 app will display the result with pagination:

angular-13-pagination-example-ngx-pagination-default-paging

You can change to a page with larger index:

angular-13-pagination-example-ngx-pagination-change-page

Or change quantity of items per page:

angular-13-pagination-example-ngx-pagination-change-items-per-page

Or paging with filter:

angular-13-pagination-example-ngx-pagination-paging-filter

The API for this Angular client can be found at one of following posts:
Node.js Express Pagination with MySQL
Node.js Express Pagination with PostgreSQL
Node.js Express Pagination with MongoDB
Spring Boot Pagination & Filter example | Spring JPA, Pageable
Spring Boot MongoDB Pagination example with Spring Data

These Servers will exports API for pagination (with/without filter), here are some url samples:

  • /api/tutorials?page=1&size=5
  • /api/tutorials?size=5: using default value for page
  • /api/tutorials?page=1: using default value for size
  • /api/tutorials?title=data&page=1&size=3: pagination & filter by title containing ‘data’

This is structure of the response (server-side pagination) for the HTTP GET request:

{
    "totalItems": 8,
    "tutorials": [...],
    "totalPages": 3,
    "currentPage": 1
}

This is a kind of server-side paging, where the server sends just a single page at a time. ngx-pagination supports this scenario, so We actually only need to use tutorials and totalItems when working with this library.

ngx-pagination with Angular 13

ngx-pagination provides NgxPaginationModule for displaying pagination with numbers and responsive style.

There are 2 main things that we’re gonna use:

  • PaginatePipe: placed at the end of an ngFor expression
  • <your-element *ngFor="let item of collection | paginate: { id: 'foo',
                                                          itemsPerPage: pageSize,
                                                          currentPage: page,
                                                          totalItems: total }">...</your-element>
    

    Use the id if you need to support more than one instance of pagination at a time.

  • PaginationControlsComponent: a default component for displaying pagination controls
  • <pagination-controls></pagination-controls>
    

For example, this is the default display for simple pagination-controls above:

ngx-pagination-example-angular-13-default-pagination-controls

We can customize the label displayed on the “previous”/”next” link using previousLabel/nextLabel, and enable “responsive” to hide individual page links on small screens.

<pagination-controls
  previousLabel="Prev"
  nextLabel="Next"
  responsive="true"
></pagination-controls>

ngx-pagination-example-angular-13-customize-pagination-controls

For handling page changes, we pass handlePageChange to pageChange.
Notice that count is totalItems in the API response, and page is the current page.

<pagination-controls
  (pageChange)="handlePageChange($event)"
></pagination-controls>

<ul>
  <li
    *ngFor="let tutorial of tutorials | paginate: {
              itemsPerPage: pageSize,
              currentPage: page,
              totalItems: count
            }"
  >
    {{ tutorial.title }}
  </li>
</ul>
@Component(...)
export class TutorialsListComponent {
  ...
  page = 1;

  handlePageChange(event) {
    this.page = event;
  }

}

pageChange is the expression invoked whenever the page changes via a click on the pagination controls. The $event argument will be the number of the new page.

There are more attributes that ngx-pagination supports:

<pagination-controls  id="some_id"
                      (pageChange)="pageChanged($event)"
                      (pageBoundsCorrection)="pageChanged($event)"
                      maxSize="9"
                      directionLinks="true"
                      autoHide="true"
                      responsive="true"
                      previousLabel="Previous"
                      nextLabel="Next"
                      screenReaderPaginationLabel="Pagination"
                      screenReaderPageLabel="page"
                      screenReaderCurrentLabel="You're on page">
</pagination-controls>

You can find the details at: https://www.npmjs.com/package/ngx-pagination.

Technology

  • Angular 13
  • RxJS 7
  • ngx-pagination 5

Setup Angular 13 Application

Let’s open cmd and use Angular CLI to create a new Angular Project as following command:

ng new Angular13Pagination
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? CSS

You can follow step by step, or get source code in this post:
Angular 13 CRUD Application with Rest Api

The Angular 13 Project contains structure that we only need to add some changes (in tutorials-list component and tutorial.service.ts) to make the pagination work well.

angular-13-pagination-example-project-structure

Or you can get the new Github source code at the end of this tutorial.

Setup ngx-pagination for Angular 13 Pagination example

We need to install ngx-pagination with command:
npm install ngx-pagination --save

Then open app.module.ts and import it:

...
import { HttpClientModule } from '@angular/common/http';
import { NgxPaginationModule } from 'ngx-pagination';

@NgModule({
  declarations: [ ... ],
  imports: [
    ...
    NgxPaginationModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Create Data Service

This service will use Angular HttpClient to send HTTP requests.

services/tutorial.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Tutorial } from '../models/tutorial.model';

const baseUrl = 'http://localhost:8080/api/tutorials';

@Injectable({
  providedIn: 'root'
})
export class TutorialService {

  constructor(private http: HttpClient) { }

  getAll(params: any): Observable<any> {
    return this.http.get<any>(baseUrl, { params });
  }

  // other CRUD operations
}

In the code above, you can see that we pass params object to GET method.
The params object will have one, two or all fields: title, page, size.

Create Angular 13 Component with Pagination

This component has:

  • a search bar for finding Tutorials by title.
  • a select element for quantity of items per page.
  • a PaginationControlsComponent component
  • a tutorials array displayed as a list on the left.
  • a selected Tutorial which is shown on the right.

angular-13-pagination-example-ngx-pagination-default-paging

components/tutorials-list/tutorials-list.component.html

<div class="list row">
  <div class="col-md-8">
    <div class="input-group mb-3">
      <input
        type="text"
        class="form-control"
        placeholder="Search by title"
        [(ngModel)]="title"
      />
      <div class="input-group-append">
        <button
          class="btn btn-outline-secondary"
          type="button"
          (click)="searchTitle()"
        >
          Search
        </button>
      </div>
    </div>
  </div>

  <div class="col-md-12">
    <pagination-controls
      previousLabel="Prev"
      nextLabel="Next"
      [responsive]="true"
      (pageChange)="handlePageChange($event)"
    ></pagination-controls>
  </div>

  <div class="col-md-6">
    <h4>Tutorials List</h4>

    <ul class="list-group">
      <li
        class="list-group-item"
        *ngFor="
          let tutorial of tutorials | paginate : {
                  itemsPerPage: pageSize,
                  currentPage: page,
                  totalItems: count
                };
          let i = index
        "
        ...
      >
        {{ tutorial.title }}
      </li>
    </ul>
  </div>
  ...

  <div class="mt-3">
    ...

    Items per Page:
    <select (change)="handlePageSizeChange($event)">
      <option *ngFor="let size of pageSizes" [ngValue]="size">
        {{ size }}
      </option>
    </select>
  </div>
</div>

We will have following variables:
– search and display Tutorials:

  • title
  • tutorials
  • currentTutorial and currentIndex

– pagination:

  • page: current page
  • count: total pages
  • pageSize: number of items in each page

For pagination, we’re gonna use TutorialService.getAll() methods.

components/tutorials-list/tutorials-list.component.ts

import { Component, OnInit } from '@angular/core';
import { Tutorial } from 'src/app/models/tutorial.model';
import { TutorialService } from 'src/app/services/tutorial.service';

@Component({
  selector: 'app-tutorials-list',
  templateUrl: './tutorials-list.component.html',
  styleUrls: ['./tutorials-list.component.css']
})
export class TutorialsListComponent implements OnInit {

  tutorials: Tutorial[] = [];
  currentTutorial: Tutorial = {};
  currentIndex = -1;
  title = '';

  page = 1;
  count = 0;
  pageSize = 3;
  pageSizes = [3, 6, 9];

  constructor(private tutorialService: TutorialService) { }

  ngOnInit(): void {
    this.retrieveTutorials();
  }

  getRequestParams(searchTitle: string, page: number, pageSize: number): any {
    let params: any = {};

    if (searchTitle) {
      params[`title`] = searchTitle;
    }

    if (page) {
      params[`page`] = page - 1;
    }

    if (pageSize) {
      params[`size`] = pageSize;
    }

    return params;
  }

  retrieveTutorials(): void {
    const params = this.getRequestParams(this.title, this.page, this.pageSize);

    this.tutorialService.getAll(params)
    .subscribe(
      response => {
        const { tutorials, totalItems } = response;
        this.tutorials = tutorials;
        this.count = totalItems;
        console.log(response);
      },
      error => {
        console.log(error);
      });
  }

  handlePageChange(event: number): void {
    this.page = event;
    this.retrieveTutorials();
  }

  handlePageSizeChange(event: any): void {
    this.pageSize = event.target.value;
    this.page = 1;
    this.retrieveTutorials();
  }

  ...

  searchTitle(): void {
    this.page = 1;
    this.retrieveTutorials();
  }
}

Let me explain some lines of code.

In the retrieveTutorials() method:
– We get title, page, pageSize value and transform them into params object:

{
    "title": searchTitle,
    "page": page - 1,
    "size": pageSize
}

– We use tutorials and totalItems as count value from the response data:

{
    "totalItems": 8,
    "tutorials": [...],
    "totalPages": 3,
    "currentPage": 1
}

handlePageChange() and handlePageSizeChange() methods are for setting new page and pageSize, then we invoke retrieveTutorials() that updates the tutorials List when pagination information changes.

Run Angular 13 Pagination example

First you need to run the Server at one of following posts:

Then you can run our App with command: ng serve --port 8081.
If the process is successful, open Browser with Url: http://localhost:8081/ and check it.

Conclusion

Today we’ve built a Angular 13 Pagination example that consume API (server-side pagination) successfully with ngx-pagination. I hope you apply it in your project at ease.

Happy learning, see you again!

Further Reading

Fullstack with Node.js Express:
Server side Pagination with Node.js and Angular

Fullstack with Spring Boot:
Spring Boot + Angular: Server side Pagination example

Source Code

You can find the complete source code for this tutorial on Github.

2 thoughts to “Angular 13 Pagination example (server side) with ngx-pagination”

  1. I do not understand why you call it server side pagination. The pagination is done by the client (angular) based on the complete result list. I.e. to determine the totalSize you request the complete result list from the server.

    I would appreciate an example that requests the total size first and then requests the data for each page seperately from the server giving pageSize and pageIndex, since it does not make sense to request MB of data from the server in order to page this on the client. Maybe only the first few pages will be paged by the customer.

    Regards, Heike

    1. Hi, why can’t I call it server side pagination?
      You said: “The pagination is done by the client (angular) based on the complete result list. I.e. to determine the totalSize you request the complete result list from the server.”

      But the Angular client in the tutorial requests data for each page (by specifying page size and page index). It doesn’t request MB of data from the server then make pagination as you said.

Comments are closed to reduce spam. If you have any question, please send me an email.