When our frontend gets a paginated result from an API, we have to handle not only paging, but also sorting of the outcome. In this post, I show how to create a custom sorting component that works well with a standard
Page object returned by a Spring Boot API.
What we are going to build
The goal is to build a custom sorting component that accepts a paginated response from a Spring Boot API and displays it in a data table. We will be able to control the sorting direction and a column that will be used to arrange records.
Our example app will be displaying a list of projects fetched from the
"/api/projects" endpoint exposed by the backend API.
The finished project is available in the GitHub repository – little-pinecone/scrum_ally.
You can see the datatable from that project, with sorting, on the following screenshot:
You can see the final directory tree for the sorting part of the frontend app on the image below:
- Angular CLI – a command line interface tool that generates projects, components, modules, services.
I’m working on:
- To see the backend part of this example web application, check out the Add pagination to a Spring Boot app post.
- You need to handle the backend pagination. Make sure to read the Handle server-side pagination in an Angular application post first.
Consume a page received from a Spring Boot app
Make sure, that the frontend is able to consume a page received from an API. We are doing it by mirroring the
Page instance (code from the Handle server-side pagination in an Angular application post):
Adjust the default
pageSize to your needs.
Create a sortable-column class
We need a class that will carry the internal name, displayed title and sorting direction of a column:
Let’s add a function for toggling the direction of the sorting, it will be called every time a user clicks a column title:
The first click results in setting the ascending order, the second click gives the descending order and the third click clears sorting (the arrow won’t be shown and the records will be sorted by id, ascending, by default).
Create a sortable-header component
Generate the component with the following command:
Copy the following code to make the component accept an array filled with sortable-column objects and emit events when users trigger sorting:
An html template displays columns titles in
<th> elements. On the right of every title there is a place for a sort icon – it reflects the chosen sorting direction. The icon is displayed only for a column for which the sorting was activated:
A user triggers
sort() function by clicking the column title.
Add a service to handle base actions
Use the following command to generate a service:
In this service we are going to add two public methods. One for getting the column that has a non-null sort direction set – that’s the column chosen by a user:
The other, for setting direction in all other columns to
null – it will remove a sorting icon displayed in a datatable from a previously chosen column:
The service and our component are ready to be used in all components that serves datatables.
Include our sorting feature in a datatable
In the template with the datatable (e.g.
projects-table.component.html), replace the old
<th> elements (e.g
) with the
Now, we need to provide the actual
sortableColumns array. Declare it in the component that serves the view (e.g.
If you provide column names, titles (displayed in the view) and sort order (for the one you choose as a default sorting column), the records will be sorted when your app loads the view.
When adding more columns, remember to leave the third parameter,
direction, set to
null. Only one column should have the direction set to
'desc' value. The
direction in the rest of them has to be set to
Let’s provide the implementation of the
sort() method, called when a user clicks a column title:
sort() method is called, the column for which it was triggered is filtered out from the list of all columns so we can set the
direction field in the rest of them to null.
Then, we call the
getData() function, so let’s take a look at the implementation:
getData() function is called every time the page is loaded, refreshed, the pagination has been changed, so it has to be able to retrieve the sorting column. It does so by using the
sortingSercive we created previously. Next, it can pass the chosen column to the
projectDataService. Now, we can move on to the next step – adjusting the service so it can pass sorting parameters to the backend.
Update a service that handles requests
getPage() method accepts two arguments:
sortableColumn. If the sortableColumn is null, the response will be sorted by the id of the records by default. However, if it is set, the column name and the sort direction will be passed to the backend, as you can see below:
Thanks to that, you are able to pass the sort parameters alongside the paging parameters to the API and receive a nice, paginated and already sorted response.
Test the sorting feature
|I updated the example project to Angular 8 and realised that some fixes are required. You will find them in the commit 1057f352abc.
Updated CustomSortingService test.
Add those tests to our
custom-sorting.service.spec.ts file :
You also need to updated tests for all components that uses the