Angular Material Pagination Made Easy: Step-by-Step Guide for Navigation
In this post you will learn how to implement pagination from Angular Material.
Not so long ago I created a post about implementing custom pagination inside Angular. I still think that the custom way is a way to go because you are super flexible and pagination is not the most difficult component.
But some people wrote that they still prefer a library solution this is why in this video we will look how we can implement pagination from Angular Material.
Angular Material installation
Here I already prepared for us an empty Angular project and the first thing that we need to do is install Angular Material package.
npm install @angular/material
But it is not all. There is an additional dependency for Angular Material which is called Angular CDK.
npm install @angular/cdk
Configuring CSS
The next step is to configure our CSS from Angular Material.
As you can see on the official website paginator has nice CSS with items per page dropdown, pages information and buttons to switch the page. Everything here has nice CSS and transitions that we can get out of the box.
But in order to use it we need to install a theme of Angular Material in our project. In order to do that we must all theme CSS in angular.json
.
"styles": [
"@angular/material/prebuilt-themes/indigo-pink.css",
"src/styles.css"
],
This will import prebuilt theme from Angular Material in our app.
Fonts & Icons
The last configuration that we need are fonts and icons from Angular Material.
// src/index.html
<html lang="en">
<head>
...
<link
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap"
rel="stylesheet"
/>
<link
href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet"
/>
</head>
<body class="mat-typography">
<app-root></app-root>
</body>
</html>
We must add both imports to our index.html
. And actually they are suitable for all components and not just for pagination. We also added a class mat-typography
to our body.
Setting up pagination
In our to use pagination we must do some imports.
import { MatPaginatorModule } from '@angular/material/paginator';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
...
imports: [
...
MatPaginatorModule,
BrowserAnimationsModule,
],
bootstrap: [AppComponent],
})
export class AppModule {}
Here we need to import not only MatPaginatorModule
which is needed for our pagination but also BrowserAnimationsModule
as it uses some Angular animations inside.
Now we can render our pagination.
<mat-paginator
[length]="500"
[pageSize]="20"
[showFirstLastButtons]="true"
[pageSizeOptions]="[5, 10, 20]"
[pageIndex]="currentPage"
(page)="handlePageEvent($event)"
>
</mat-paginator>
Here are all options that we need. length
is a total amount of entities inside database. Paginator needs this information to calculate the amount of pages. pageSize
is our limit of elements per page. showFirstLastButtons
means that we want to see first and last buttons. pageSizeOptions
are options for the dropdown where we can select how many items we need to show. pageIndex
is an index of activated page and page
output will be triggered when we select other page.
export class AppComponent {
currentPage = 0;
handlePageEvent(pageEvent: PageEvent) {
console.log('handlePageEvent', pageEvent);
this.currentPage = pageEvent.pageIndex;
}
}
Here we defined our currentPage
and handlePageEvent
which is triggered every time when we jump to another page.
As you can see our pagination is already rendered and is working just fine.
Overriding default behaviour
But we have a problem. As you can see on the screen instead of page information we see offset information which doesn't make any sense for user. This is what what I want to do is override this test to render meaningful information inside.
In order to do that we must extend and override service from paginator.
// src/app/paginatorIntl.service.ts
import {Injectable} from "@angular/core";
import {MatPaginatorIntl} from "@angular/material/paginator";
@Injectable()
export class PaginatorIntl extends MatPaginatorIntl {
override getRangeLabel = (page: number, pageSize: number, length: number) => {
return `Page ${page + 1} of ${Math.ceil(length/pageSize)}`
}
}
Here we extended it from MatPaginatorIntl
and overrode getRangeLabel
. This is exactly what we see in pages information.
Now we just need to inject it correctly.
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [{ provide: MatPaginatorIntl, useClass: PaginatorIntl }],
})
export class AppComponent {}
Here we provided our class inside the component as a MatPaginatorIntl
provider. This means that instead of default service it will use our implementation.
As you can see in browser it looks much better and the text is meaningful.
Want to conquer your next JavaScript interview? Download my FREE PDF - Pass Your JS Interview with Confidence and start preparing for success today!
📚 Source code of what we've done![](https://cdn.monsterlessons-academy.com/mla-website/author-in-course.png)