Tutorial: “Spring Boot Angular Pagination Example – Angular Table Pagination Filtering Sorting with SpringBoot RestAPIs + Bootstrap Example”
When we have a large dataset and we want to present it to the user in smaller chunks, pagination and sorting is often helpful solution. So in the tutorial, I introduce how to use Angular to build a table solution for pagination, filtering and sorting the fetching data with SpringBoot RestAPIs examples.
Overview Spring Boot Angular Pagination Example

In the tutorial, We develop 2 projects:
- Backend Project – SpringBoot Application gets data from MySQL/PostgreSQL database then provides RestAPIs with pagination, filtering and sorting function for frontend
- Frontend Project – Angular Application use HttpClient to fetch data from Backend Application then shows them in Bootstrap table with pagination, filtering and sorting functions
Project Goal – Spring Boot Angular Pagination Example
– Make a request at API: /api/customers/custom/pageable
with pagination, filtering and sorting params as below:
page
: 0 – first pagesize
: 5 – size of a pagesalary
: 4000 – filtering bysalary
fieldagesorting
: true – sorting by agedesc
: true – descending or ascending sorting
– Result:

– Angular Frontend Pagination with Filtering and Sorting table:

SpringBoot Pagination Filtering and Sorting RestAPIs – Spring Boot Angular Pagination Example
For doing the pagination, we use PagingAndSortingRepository
class that is an extension of CrudRepository
to provide additional methods to retrieve entities using the pagination and sorting abstraction. Here is the sourcecode of it:
@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);
}
findAll(Sort sort)
returns all entities sorted by the given options.findAll(Pageable pageable)
Returns a page of entities meeting the paging restriction provided in thePageable
object.
Here is the hierarchy of PagingAndSortingRepository
:

So JpaRepository
of Spring JPA is an alternative solution for PagingAndSortingRepository
:
@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
Spring Boot JPA Pagination – Spring Boot Angular Pagination Example
For pagination with Spring JPA, we use the methods:
Page<T> findAll(Pageable pageable);
It returns a Page
of entities meeting the paging restriction provided in the Pageable
object.
– Here is how the Page
interface is defined:

– Here is how to Pageable
interface is defined:

Examples coding:
Pageable requestedPage = PageRequest.of(0, 5);
Page<Customer> customers = customerRepository.findAll(requestedPage);
We use the PageRequest
to construct a Pageable
object then pass it to the findAll()
method of PagingAndSortingRepository
.
SpringBoot How to Pagining and Filtering? – Spring Boot Angular Pagination Example
For filtering data with pagination, Spring JPA provides many useful Query Creation from method names:
Slice findAllBySalary (double salary, Pageable pageable);
Page findAllByAgeGreaterThan(int age, Pageable pageable);
GreaterThan
examplesfindAllByAgeGreaterThan(int age, Pageable pageable);
means… where x.age> ?1
Is, Equals
examplesfindAllBySalary (double salary, Pageable pageable)
means… where x.salary = ?1
SpringBoot Paging and Sorting – Spring Boot Angular Pagination Example
For sorting with Spring data JPA, we use the function: Iterable<T> findAll(Sort sort);
.
We can use public static methods by()
to build the Sort objects:
public static Sort by(String... properties)
creates a newSort
for the given properties.public static Sort by(List≶Order> orders)
creates a newSort
for the given list Orderspublic static Sort by(Order... orders)
create a newSort
for the givenOrder
spublic static Sort by(Direction direction, String... properties)
If we want to both sort and page our data, We can do that by passing the sorting details into our PageRequest
object itself:
Pageable sortedBySalary =
PageRequest.of(0, 3, Sort.by("salary"));
Pageable sortedBySalaryDesc =
PageRequest.of(0, 3, Sort.by("salary").descending());
Pageable sortedBySalaryDescAgeAndFirstnameAsc =
PageRequest.of(0, 5, Sort.by("salary").descending().and(Sort.by("age")).and(Sort.by("firstname")));
For more details about how to builld a SpringBoot RestAPIs for pagination, filtering and sorting, please follow the link at here.
Create SpringBoot Project – Spring Boot Angular Pagination Example
We create a SpringBoot project with 3 dependencies:
- Spring Web is used to handle RestAPIs
- Spring JPA is used to do pagination, filtering and sorting with database’s data
- MySQL/PostgreSQL driver is used to work with dabase
Check the pom.xml
file:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
SpringBoot Configure Database – Spring Boot Angular Pagination Example
Open the application.properties
to configure the working database environment:
spring.datasource.url=jdbc:mysql://localhost:3306/loizenjavadb spring.datasource.username=root spring.datasource.password=12345 spring.jpa.generate-ddl=true #drop & create table again, good for testing, comment this in production spring.jpa.hibernate.ddl-auto=create
SpringBoot Create JPA Data Model – Spring Boot Angular Pagination Example
We create a Customer
model class with 7 attributes: id
, firstname
, lastname
, address
, age
, salary
, copyrightBy
.

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="customer")
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column
private String firstname;
@Column
private String lastname;
@Column
private String address;
@Column
private int age;
@Column
private double salary;
@Column(columnDefinition = "varchar(255) default '@ https://loizenjava.com'")
private String copyrightBy;
– @Column
specifies the mapped column for a persistent property or field. If no Column annotation is specified, the default values apply.
– javax.persistence.Id
specifies the primary key of an entity.
– javax.persistence.Entity
specifies that the class is an entity. This annotation is applied to the entity class.
SpringBoot Define JPA Paging and Sorting Repository – Spring Boot Angular Pagination Example
Create interface CustomerRepository
extends PagingAndSortingRepository
:
package com.loizenjava.springboot.pagingansorting.repository;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import com.loizenjava.springboot.pagingansorting.model.Customer;
@Repository
public interface CustomerRepository extends PagingAndSortingRepository<Customer, Long>{
Page<Customer> findAllBySalary (double salary, Pageable pageable);
@Query("SELECT DISTINCT c.salary FROM Customer c")
List<Double> findDistinctSalary();
}
Implement SpringBoot Pagination Filtering and Sorting RestAPI
We implement a SpringBoot RestAPI at URL /api/customers/custom/pageable
to do pagination, filtering and sorting Customer with 5 params:
page
is used to get the right pagesize
is a size of a pagesalary
is used to filteringagesorting
is used to sort withage
column or notdesc
is used to define the sorting direction – descending or default with ascending sorting
Coding:
package com.loizenjava.springboot.pagingansorting.restapis;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.query.Param;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.loizenjava.springboot.pagingansorting.model.Customer;
import com.loizenjava.springboot.pagingansorting.model.Response;
import com.loizenjava.springboot.pagingansorting.repository.CustomerRepository;
@org.springframework.web.bind.annotation.RestController
@RequestMapping("/api/customers")
@CrossOrigin(origins = "http://localhost:4200")
public class RestController {
@Autowired
CustomerRepository customerRepository;
@GetMapping("/custom/pageable")
public Response retrieveCustomer(@Param(value = "salary") int salary,
@Param(value = "page") int page,
@Param(value = "size") int size,
@Param(value = "agesorting") boolean agesorting,
@Param(value = "desc") boolean desc){
Page<Customer> customers = null;
// not filtering with salary
if(salary < 0) {
// not sorting with age
if(agesorting == false) {
Pageable requestedPage = PageRequest.of(page, size);
customers = customerRepository.findAll(requestedPage);
}else {
// sorting with age and ascending
if(false == desc) {
Pageable requestedPage = PageRequest.of(page, size, Sort.by("age"));
customers = customerRepository.findAll(requestedPage);
}
// sorting with age and descending
else {
Pageable requestedPage = PageRequest.of(page, size,
Sort.by("age").descending());
customers = customerRepository.findAll(requestedPage);
}
}
// Filtering with salary
} else {
// not sorting with age
if(agesorting == false) {
Pageable requestedPage = PageRequest.of(page, size);
// fitering request
customers = customerRepository.findAllBySalary(salary, requestedPage);
}else {
// sorting with age and ascending
if(false == desc) {
Pageable requestedPage = PageRequest.of(page, size, Sort.by("age"));
// filtering request
customers = customerRepository.findAllBySalary(salary, requestedPage);
}
// sorting with age and descending
else {
Pageable requestedPage = PageRequest.of(page, size,
Sort.by("age").descending());
// filtering request
customers = customerRepository.findAllBySalary(salary, requestedPage);
}
}
}
Response res = new Response(customers.getContent(), customers.getTotalPages(),
customers.getNumber(), customers.getSize());
return res;
}
@GetMapping("/salaries")
public List<Double> getListSalaries() {
try {
return customerRepository.findDistinctSalary();
}catch(Exception e) {
// Log errors to user monitoring
System.out.println(e);
return Arrays.asList();
}
}
}
Implement SpringBoot Main Class – Spring Boot Angular Pagination Example
In the main class of SpringBoot project, We implement the CommandLineRunner
interface and inject the CustomerRepository
repository to save a list Customer
to database MySQL/PostgreSQL.
Coding:
package com.loizenjava.springboot.pagingansorting;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.loizenjava.springboot.pagingansorting.model.Customer;
import com.loizenjava.springboot.pagingansorting.repository.CustomerRepository;
@SpringBootApplication
public class SpringBootPagingAndSortingApplication implements CommandLineRunner{
@Autowired
CustomerRepository customerRepository;
public static void main(String[] args) {
SpringApplication.run(SpringBootPagingAndSortingApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
List<Customer> customers = Arrays.asList( new Customer("Jack", "Smith", "Massachusetts", 23, 4000)
, new Customer("Adam", "Johnson", "New York", 27, 3000)
, new Customer("Katherin", "Carter", "Washington DC", 26, 4000)
, new Customer("Jack", "London", "Nevada", 33, 4000)
, new Customer("Jason", "Bourne", "California", 36, 3000)
, new Customer("Blade", "Johnson", "Ohio", 18, 3000)
, new Customer("Carol", "Carter", "Florida", 23, 4000)
, new Customer("Avery", "Alvin", "Washington DC", 41, 3000)
, new Customer("Dana", "Bay", "Texas", 32, 4000)
, new Customer("Tom", "Bourne", "Colorado", 28, 3500)
, new Customer("Ardys", "Bean", "Alaska", 23, 4000)
, new Customer("Carol", "Carter", "Arizona", 26, 3500)
, new Customer("Avery", "Zane", "Virginia", 31, 4000)
, new Customer("Barric", "Weldin", "Oregon", 52, 3000)
, new Customer("Galen", "Wayt", "Missouri", 48, 4000)
, new Customer("Mayer", "Acomb", "Wisconsin", 32, 4000)
, new Customer("Sadie", "Albright", "Tennessee", 23, 3500)
, new Customer("Norvell", "Baily", "Oregon", 41, 4000)
, new Customer("Tanzi", "Baney", "North Dakota", 26, 4000)
, new Customer("Osric", "Callender", "New Mexico", 29, 3000)
, new Customer("Trudy", "Zane", "Vermont", 31, 3500)
, new Customer("Reynold", "Zone", "Wyoming", 43, 3000)
, new Customer("Udele", "Wheetley", "Michigan", 37, 3500)
, new Customer("Blackburn", "Atkinson", "Illinois", 19, 4000)
, new Customer("Cotovatre", "Bailey", "Delaware", 26, 4000));
customerRepository.saveAll(customers);
}
}
Testing SpringBoot Pagination RestAPI – Spring Boot Angular Pagination Example
1. SpringBoot RestAPI Testcase 1 – Get All Distinct Salaries:
– Make a request to ULR: /api/customers/salaries

2. SpringBoot RestAPI Testcase 2 – Pagination Filtering and Sorting RestAPI:
– Make a request at API: /api/customers/custom/pageable
with pagination, filtering and sorting params as below:
page
: 0 – first pagesize
: 5 – size of a pagesalary
: 4000 – filtering bysalary
fieldagesorting
: true – sorting by agedesc
: true – descending or ascending sorting
– Result:

Angular Pagination Features Overview – Spring Boot Angular Pagination Example

We create an Angular Application with 2 main blocks:
- CustomerService is used to fetch data through Angular HTTP Client
- TableComponent is used to display data with pagination, filtering and sorting view

Here is the Angular project structure:

– We implement a component: angulartable
with 2 files angulartable.component.html
and angular.component.ts
to display data on web.
– We implement a service customer.service.ts
using Httpclient to interact with SpringBoot restPAPI to fetch data with pagination, filtering and sorting.
– We define 2 helpful class customer.ts
and message.ts
for mapping data with RestAPIs.
Create Angular Pagination Project – Spring Boot Angular Pagination Example
Create an Angular project by commandline: ng new AngularTable
Create an Angular component by cmd: ng generate c angulartable
Create an Angular service by cmd: ng gererate s customer
Create Angular classes customer.ts
and message.ts
by cmd:
– ng generate class customer
– ng generate class message
Define Angular Customer.ts class
export class Customer {
id: number;
firstname: string;
lastname: string;
age: number;
salary: number;
address: string;
copyrightBy: string;
}
Define Angular Message.ts class
import { Customer } from './customer';
export class Message {
customers: Customer[];
totalPages: number;
pageNumber: number;
pageSize: number;
}
Implement Angular Customer Service
We implement CustomerService
service which uses a built-in HttpClient of Angular to create 2 http methods:
getPagableCustomers()
is used to a Page of Customer from SpringBoot RestAPI with 5 params for pagination, filtering and sorting datagetListSalaries()
is used to get a list distinct salaries of Customer
Coding:
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpParams } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
import { Message } from './message';
@Injectable({
providedIn: 'root'
})
export class CustomerService {
private baseUrl = 'http://localhost:8080/api/customers';
constructor(private http: HttpClient) { }
/**
* Retrieve all customer from Backend
*/
getPagableCustomers(pageNumber: number,
pageSize: number, salary: number,
agesorting: boolean, desc: boolean): Observable<Message> {
// Initialize Params Object
let params = new HttpParams();
// Begin assigning parameters
params = params.append('page', pageNumber.toString());
params = params.append('size', pageSize.toString());
params = params.append('salary', salary.toString());
params = params.append('agesorting', agesorting.toString());
params = params.append('desc', desc.toString());
return this.http.get<Message>(`${this.baseUrl}` + `/custom/pageable`, { params: params })
.pipe(
retry(3),
catchError(this.handleError)
);
}
getListSalaries(): Observable<Array<number>>{
return this.http.get<Array<number>>(`${this.baseUrl}` + `/salaries`)
.pipe(
retry(3),
catchError(this.handleError)
);
}
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
// return an observable with a user-facing error message
return throwError(
'Something bad happened; please try again later.');
};
}
Develop Angular Table Component
1. Implement View Page:
We use Bootstrap to implement the view page, so we need add it to the head tag of index.html
page.
– Coding of index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>AngularHttpclient</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container" >
<div class="col-sm-7" style="background-color: #e6f9ff; margin:10px;padding:10px; border-radius: 5px">
<div class="alert alert-danger">
<h3>Angular + SpringBoot Tutorial</h3>
<h6><strong>Pagination + Filtering and Sorting </strong></h6>
<hr>
<p>@Copyright by <strong><span style="color:blue"><a href="https://loizenjava.com">https://loizenjava.com</a></span></strong><br>
youtube: <strong><a href="https://www.youtube.com/channel/UChkCKglndLes1hkKBDmwPWA"><span style="color:crimson">loizenjava</span></a></strong>
</p>
</div>
<app-root></app-root>
</div>
</div>
</body>
</html>
To display data with pagination, filtering and sorting, we develop table component to do the task with 3 main parts for Angular view page:
- a Bootstrap table with a pagination bar to display data and selecting a specific pagination
- a Select List for distinct salaries to choose a specific salary for doing the pagination with salary filtering
- a checkbox group with 2 fields
age
anddesc
to make a decission to sort or NOT with theage
field by descending or ascending direction
– Code of angulartable.component.html
view page:
<div *ngIf="customers.length">
<h3>Processing...</h3>
<br>
<div>
<h5>Do you want sorting by?</h5>
<form>
<label class="checkbox-inline">
<input type="checkbox"
[checked]="agesorting"
(change)="onAgeSortingChange($event)"> Age
<br>
<input [disabled]="!agesorting" type="checkbox"
[checked]="desc"
(change)="desc = !desc"> Desc
</label>
</form>
<button type="button" class="btn btn-primary" (click)="sortNow()">Sort Now</button>
</div>
<hr>
<div class="form-group">
<label for="sel1"><h5>Filtering by Salary:</h5></label>
<select class="form-control" id="salary_filtering"
(change)="getCustomerPagesWithSalaryFiltering($event.target.value)">
<option>All</option>
<option *ngFor="let salary of salaries">{{salary}}</option>
</select>
</div>
<h3>Customers</h3>
<table class="table table-hover table-sm">
<thead class="thead-dark">
<tr>
<th>Id</th>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
<th>Salary</th>
<th>Address</th>
<th>Copyright By</th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let customer of customers">
<td>{{customer.id}}</td>
<td>{{customer.firstname}}</td>
<td>{{customer.lastname}}</td>
<td>{{customer.age}}</td>
<td>{{customer.salary}}</td>
<td>{{customer.address}}</td>
<td><a href="https://loizenjava.com">{{customer.copyrightBy}}</a></td>
</tr>
</tbody>
</table>
</div>
<ul class="pagination justify-content-center">
<li class="page-item"><a (click)="previousClick()" class="page-link">Previous</a></li>
<li *ngFor='let index of pageIndexes' class="page-item" [ngClass]="active(index)">
<a (click)="getPaginationWithIndex(index)" class="page-link">
{{index + 1}}
</a>
</li>
<li class="page-item"><a (click)="nextClick()" class="page-link">Next</a></li>
</ul>
2. Implement Table Component:
We develop Table Component angulartable.component.ts
arround below list of variables:
currentSelectedPage:number = 0;
totalPages: number = 0;
customers: Array<Customer> = [];
pageIndexes: Array<number> = [];
// salaries list
salaries: Array<number> = [];
selectedSalary: number = -1;
// sorting
agesorting: boolean = false;
desc: boolean = false;
What does it mean?
currentSelectedPage
defines the current selected page for getting datatotalPages
is the number page of data for paginationcustomers
contains a list customers of current fetching pagepageIndexes
contains an array numbers that presents the number of pages to show for user selectingsalaries
contains a list of salaries with distinct valuesselectedSalary
is a selected salary for filtering with paginationageSorting
is a boolean variable that determines whether the sorting withage
field or notdesc
is a boolean variable that is used to determines a direction for sorting by descending or ascending (the default value)
We use the CustomerService
to fetch data from SpringBoot RestAPIs, so we need to inject it in the constructor:
constructor(private customerService: CustomerService) {
}
Angular Show the fetching data with Table and Pagination Bar
For getting data from SpringBoot RestAPI, we define a function getPage()
as below:
getPage(page: number, selectedSalary: number, agesorting: boolean, desc: boolean){
this.customerService.getPagableCustomers(page, pageSize, selectedSalary,
agesorting, desc)
.subscribe(
(message: Message) => {
console.log(message);
this.customers = message.customers;
this.totalPages = message.totalPages;
this.pageIndexes = Array(this.totalPages).fill(0).map((x,i)=>i);
this.currentSelectedPage = message.pageNumber;
},
(error) => {
console.log(error);
}
);
}
At the initial time of Angular loading page, we need invoke the getPage
function with appropriate parameters as below code:
ngOnInit(): void {
// get the first Page
this.getPage(0, -1, false, false);
// get Salaries
this.getSalaries();
}
On the view page, for showing the fetching data, we need binding them as below html code using the Angular directive:
<tbody>
<tr *ngFor="let customer of customers">
<td>{{customer.id}}</td>
<td>{{customer.firstname}}</td>
<td>{{customer.lastname}}</td>
<td>{{customer.age}}</td>
<td>{{customer.salary}}</td>
<td>{{customer.address}}</td>
<td><a href="https://loizenjava.com">{{customer.copyrightBy}}</a></td>
</tr>
</tbody>
Here is the how we build the pagination bar on Html view by binding the fetching data pageIndexes
with html element by using a Angular built-in directive *ngFor
:
<ul class="pagination justify-content-center">
<li class="page-item"><a (click)="previousClick()" class="page-link">Previous</a></li>
<li *ngFor='let index of pageIndexes' class="page-item" [ngClass]="active(index)">
<a (click)="getPaginationWithIndex(index)" class="page-link">
{{index + 1}}
</a>
</li>
<li class="page-item"><a (click)="nextClick()" class="page-link">Next</a></li>
</ul>
For processing the navigation with Next
and Previous
buttons on Pagination bar, we define 2 funtions nextClick()
and previousClick()
as below:
nextClick(){
if(this.currentSelectedPage < this.totalPages-1){
this.getPage(++this.currentSelectedPage,
this.selectedSalary, this.agesorting, this.desc);
}
}
previousClick(){
if(this.currentSelectedPage > 0){
this.getPage(--this.currentSelectedPage,
this.selectedSalary, this.agesorting, this.desc);
}
}
}
Angular Do The Pagination and Filtering with salary selected option
Review again the implementation in html view page for the filtering select-option form funtion:
<div class="form-group">
<label for="sel1"><h5>Filtering by Salary:</h5></label>
<select class="form-control" id="salary_filtering"
(change)="getCustomerPagesWithSalaryFiltering($event.target.value)">
<option>All</option>
<option *ngFor="let salary of salaries">{{salary}}</option>
</select>
</div>
We use the Angular built-in directive *ngFor
to build the selected-option list of distinct value of salaries.
The salaries
list is fetched at the initial time of Angular Component:
ngOnInit(): void {
...
// get Salaries
this.getSalaries();
}
getSalaries() {
this.customerService.getListSalaries()
.subscribe(
(salaries: Array<number>) => {
console.log(salaries);
this.salaries = salaries;
},
(error) => {
console.log(error);
}
);
}
If having any change from selected form, the function (change)="getCustomerPagesWithSalaryFiltering($event.target.value)
will be invoked:
getCustomerPagesWithSalaryFiltering(optionValue: any) {
// convert option string value to appropriate number
if(optionValue != "All"){
this.selectedSalary = parseInt(optionValue);
} else {
this.selectedSalary = -1;
}
// load customer again with filtering and pagination api
this.getPage(0, this.selectedSalary, this.agesorting, this.desc);
}
Angular Sorting Implementation with Age and Desc checkbox
Review again the html sorting div
:
<div>
<h5>Do you want sorting by?</h5>
<form>
<label class="checkbox-inline">
<input type="checkbox"
[checked]="agesorting"
(change)="onAgeSortingChange($event)"> Age
<br>
<input [disabled]="!agesorting" type="checkbox"
[checked]="desc"
(change)="desc = !desc"> Desc
</label>
</form>
<button type="button" class="btn btn-primary" (click)="sortNow()">Sort Now</button>
</div>
If having any changes on the checkboxes, they will immediately affect to the 2 variables agesorting
and desc
.
//.html file
(change)="onAgeSortingChange($event)"
(change)="desc = !desc"
//.ts file
onAgeSortingChange(value: any){
this.agesorting = !this.agesorting;
if(!this.agesorting){
// reset desc
this.desc = false;
}
}
When pressing the button Sort Now
, the function sortNow()
will be invoked for re-fetching the pagination and sorting data from SpringBoot RestAPI:
sortNow(){
if(this.desc == true && this.agesorting == false){
alert("Please select 'agesorting' option before selecting 'desc' option!");
return;
}
// load again from backend for sorting with age field
this.getPage(0, this.selectedSalary, this.agesorting, this.desc);
}
Angular Pagination Example – angular.component.ts code
import { Component, OnInit, ɵclearResolutionOfComponentResourcesQueue } from '@angular/core';
import { CustomerService } from '../customer.service';
import { Message } from '../message';
import { Customer } from '../customer';
const pageSize:number = 5;
@Component({
selector: 'app-angulartable',
templateUrl: './angulartable.component.html'
})
export class AngulartableComponent implements OnInit {
currentSelectedPage:number = 0;
totalPages: number = 0;
customers: Array<Customer> = [];
pageIndexes: Array<number> = [];
// salaries list
salaries: Array<number> = [];
selectedSalary: number = -1;
// sorting
agesorting: boolean = false;
desc: boolean = false;
constructor(private customerService: CustomerService) {
}
ngOnInit(): void {
// get the first Page
this.getPage(0, -1, false, false);
// get Salaries
this.getSalaries();
}
getPage(page: number, selectedSalary: number, agesorting: boolean, desc: boolean){
this.customerService.getPagableCustomers(page, pageSize, selectedSalary,
agesorting, desc)
.subscribe(
(message: Message) => {
console.log(message);
this.customers = message.customers;
this.totalPages = message.totalPages;
this.pageIndexes = Array(this.totalPages).fill(0).map((x,i)=>i);
this.currentSelectedPage = message.pageNumber;
},
(error) => {
console.log(error);
}
);
}
getPaginationWithIndex(index: number) {
this.getPage(index, this.selectedSalary, this.agesorting, this.desc);
}
getSalaries() {
this.customerService.getListSalaries()
.subscribe(
(salaries: Array<number>) => {
console.log(salaries);
this.salaries = salaries;
},
(error) => {
console.log(error);
}
);
}
getCustomerPagesWithSalaryFiltering(optionValue: any) {
// convert option string value to appropriate number
if(optionValue != "All"){
this.selectedSalary = parseInt(optionValue);
} else {
this.selectedSalary = -1;
}
// load customer again with filtering and pagination api
this.getPage(0, this.selectedSalary, this.agesorting, this.desc);
}
sortNow(){
if(this.desc == true && this.agesorting == false){
alert("Please select 'agesorting' option before selecting 'desc' option!");
return;
}
// load again from backend for sorting with age field
this.getPage(0, this.selectedSalary, this.agesorting, this.desc);
}
onAgeSortingChange(value: any){
this.agesorting = !this.agesorting;
if(!this.agesorting){
// reset desc
this.desc = false;
}
}
active(index: number) {
if(this.currentSelectedPage == index ){
return {
active: true
};
}
}
nextClick(){
if(this.currentSelectedPage < this.totalPages-1){
this.getPage(++this.currentSelectedPage,
this.selectedSalary, this.agesorting, this.desc);
}
}
previousClick(){
if(this.currentSelectedPage > 0){
this.getPage(--this.currentSelectedPage,
this.selectedSalary, this.agesorting, this.desc);
}
}
}
Integration Testing – Angular Table & SpringBoot RestAPI
1. Testcase 1 – Angular SpringBoot Pagination View:
– Start time:

– Select page 3:

2. Testcase 2 – Angular SpringBoot Pagination and Filtering View:
– Pagination and Filtering with salary is $4000:

– Pagination and Filtering with Salary = $3500:

3. Testcase 3 – Angular SpringBoot Pagination Filtering and Sorting View:
– Pagination and Filtering with salary is $3000 and Sorting by Age
:

– Pagination and Filtering with salary = $3500 and sorting by Age
with Desc
direction:

Read More
Sourcecode
– SpringBoot Sourcecode:
– SpringBoot RestAPI – GitHub Sourcode:
SpringBoot Pagination RestAPIs – GitHub
– Angular Sourcecode:
- Create Angular Project
- Define Customer.ts class
- Define Message.ts class
- Implement Customer Service
- Develop Table Component
– GitHub Source: