In this tutorial, I will show you how to make Pagination in an Angular 8 Application with existing API (server-side pagination) using ngx-pagination.
Related Posts:
– Angular 8 CRUD Application example with Web API
– Angular 8 JWT Auth – Token based Authentication with Web Api example
– Angular 8 Multiple Files upload example
Fullstack with Node.js Express:
Server side Pagination with Node.js and Angular
Fullstack with Spring Boot:
Server side Pagination with Angular 8 + Spring Boot example
Newer versions:
– Angular 10 Pagination example | ngx-pagination
– Angular 11 Pagination example | ngx-pagination
– Angular 12 Pagination example | ngx-pagination
– Angular 13 Pagination example | ngx-pagination
– Angular 14 Pagination example | ngx-pagination
– Angular 15 Pagination example | ngx-pagination
Contents
Pagination in Angular 8 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:
Our Angular 8 app will display the result with pagination:
You can change to a page with larger index:
Or change quantity of items per page:
Or paging with 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.
How to use ngx-pagination
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 anngFor
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:
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>
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 8
- RxJS 6
- ngx-pagination 5
Setup Angular 8 Application
Let’s open cmd and use Angular CLI to create a new Angular Project as following command:
ng new Angular8PaginationExample
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? CSS
We also need to generate some Components and Services:
ng g s services/tutorial
ng g c components/add-tutorial
ng g c components/tutorial-details
ng g c components/tutorials-list
Now you can see that our project directory structure looks like this.
src
app
components
add-tutorial
tutorial-details
tutorials-list
services
tutorial.service.ts
app.routing.module
app.component.html
app.component.ts
index.html
package.json
You can follow step by step, or get source code in this post:
Angular 8 CRUD Application example with Web API
The Angular 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.
Or you can get the new Github source code at the end of this tutorial.
Setup ngx-pagination for Angular 8 Pagination App
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';
const baseUrl = 'http://localhost:8080/api/tutorials';
@Injectable({
providedIn: 'root'
})
export class TutorialService {
constructor(private http: HttpClient) { }
getAll(params): Observable {
return this.http.get(baseUrl, { params });
}
// other CRUD methods
}
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 8 Components 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.
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)="retrieveTutorials()"
>
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
"
[class.active]="i == currentIndex"
(click)="setActiveTutorial(tutorial, i)"
>
{{ 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
andcurrentIndex
– pagination:
page
: current pagecount
: total pagespageSize
: 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 { 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: any;
currentTutorial = null;
currentIndex = -1;
title = '';
page = 1;
count = 0;
pageSize = 3;
pageSizes = [3, 6, 9];
constructor(private tutorialService: TutorialService) { }
ngOnInit() {
this.retrieveTutorials();
}
getRequestParams(searchTitle, page, pageSize) {
// tslint:disable-next-line:prefer-const
let params = {};
if (searchTitle) {
params[`title`] = searchTitle;
}
if (page) {
params[`page`] = page - 1;
}
if (pageSize) {
params[`size`] = pageSize;
}
return params;
}
retrieveTutorials() {
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) {
this.page = event;
this.retrieveTutorials();
}
handlePageSizeChange(event) {
this.pageSize = event.target.value;
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 8 Pagination App
First you need to run the Server 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
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 8 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
Newer versions:
– Angular 10 Pagination example | ngx-pagination
– Angular 11 Pagination example | ngx-pagination
– Angular 12 Pagination example | ngx-pagination
– Angular 13 Pagination example | ngx-pagination
Fullstack with Node.js Express:
Server side Pagination with Node.js and Angular
Fullstack with Spring Boot:
Server side Pagination with Angular 8 + Spring Boot example
Source Code
You can find the complete source code for this tutorial on Github.
Thank you!
how can we change color on selected page number
Hi, you can try to change the css:
.ngx-pagination .current { background }
can we take data recursively from api which can take less time to load data and on click of paging data of each page loads.. please share if you have any example for this scenario.
sorry i am beginner , where is setactivetutorial function?
Hi, it is in the source code (tutorials-list.component.ts) that you can find in github.
I don’t write the function in this tutorial because it’s not necessary for Pagination purpose of the tutorial.