Angular Pagination - Getting Started
Pagination is a UI component that allows users to navigate through pages and change page size at runtime.
This tutorial explains how to add Pagination to a page and configure the component's core settings. It also covers implementing remote pagination. Colored cards are loaded each time a user switches pages or changes page size. The final result is displayed below:
Each section in this tutorial describes a single configuration step. You can also find the full source code in the following GitHub repository:
Create Pagination
Add DevExtreme to your Angular application and use the following code to create a Pagination component:
- <dx-pagination></dx-pagination>
- import { Component } from '@angular/core';
- @Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
- })
- export class AppComponent {
- }
- import { BrowserModule } from '@angular/platform-browser';
- import { NgModule } from '@angular/core';
- import { AppComponent } from './app.component';
- import { DxPaginationModule } from 'devextreme-angular';
- @NgModule({
- declarations: [
- AppComponent
- ],
- imports: [
- BrowserModule,
- DxPaginationModule
- ],
- providers: [ ],
- bootstrap: [AppComponent]
- })
- export class AppModule { }
Configure Pagination
This tutorial step guides you through the basic Pagination setup.
Specify the following settings:
- itemCount sets the total number of items. Pagination does not function properly without this setting.
- pageIndex sets the initial page to display. This tutorial sets pageIndex to 3 (the default value is 1).
- allowedPageSizes specifies page sizes available to users. Modify this list as needed. Include
'all'
to allow users to display all items on one page. This tutorial uses the default value:[5, 10]
. - pageSize specifies the initial page size.
The following code snippet demonstrates how to apply the aforementioned settings:
- <dx-pagination
- [showInfo]="true"
- [showNavigationButtons]="true"
- [itemCount]="total"
- [pageIndex]="pageIndex"
- [pageSize]="pageSize"
- >
- </dx-pagination>
- import { Component } from '@angular/core';
- @Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
- })
- export class AppComponent {
- total = 100;
- pageIndex = 3;
- pageSize = 5;
- }
Implement Remote Pagination
This section explains how to implement remote pagination. Client code generates a color list and requests a remote service for cards representing color entries on the screen. The pagination component helps users browse the resulting color cards.
Implementation can be broken down into three steps:
- Generate 100 hex codes.
- Fetch color cards from The Color API service when necessary:
- On page load
- On page size changes
- On page index changes
- Display color cards obtained from the service.
Implement the first step. Generate 100 random pastel hex codes and add them to an array:
- import { Component } from '@angular/core';
- import { ColorService } from './app.service';
- @Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css'],
- providers: [ColorService],
- })
- export class AppComponent {
- // ...
- hexCodes: string[] = [];
- constructor(private readonly colorService: ColorService) {}
- ngOnInit(): void {
- this.generateHexCodes();
- }
- generateHexCodes(): void {
- for (let i = 0; i < this.total; i++) {
- this.hexCodes.push(this.colorService.getRandomPastelColor());
- }
- }
- }
- import { Injectable } from '@angular/core';
- @Injectable({
- providedIn: 'root',
- })
- export class ColorService {
- private hsvToHex(h: number, s: number, v: number): string {
- let r = 0;
- let g = 0;
- let b = 0;
- const i = Math.floor(h / 60);
- const f = h / 60 - i;
- const p = v * (1 - s);
- const q = v * (1 - f * s);
- const t = v * (1 - (1 - f) * s);
- switch (i % 6) {
- case 0: [r, g, b] = [v, t, p]; break;
- case 1: [r, g, b] = [q, v, p]; break;
- case 2: [r, g, b] = [p, v, t]; break;
- case 3: [r, g, b] = [p, q, v]; break;
- case 4: [r, g, b] = [t, p, v]; break;
- case 5: [r, g, b] = [v, p, q]; break;
- }
- const toHex = (x: number): string => Math.round(x * 255).toString(16).padStart(2, '0');
- return `${toHex(r)}${toHex(g)}${toHex(b)}`;
- }
- getRandomPastelColor(): string {
- const hue = Math.floor(Math.random() * 360);
- const saturation = Math.random() * 0.4 + 0.2;
- const brightness = Math.random() * 0.3 + 0.7;
- return this.hsvToHex(hue, saturation, brightness);
- }
- }
Fetch Data
The following code snippet demonstrates how to fetch data from the Color API:
- import { Injectable } from '@angular/core';
- @Injectable({
- providedIn: 'root',
- })
- export class ColorService {
- // ...
- fetchColorData(hex: string): Observable<Color> {
- return this.http.get<any>(`${this.apiEndpoint}${hex}`)
- .pipe(
- catchError((error: any) => throwError(() => new Error(`Error fetching color: ${error.message || error}`))),
- )
- .pipe(map((data: any) => ({
- name: data.name.value,
- image: data.image.bare,
- })));
- }
- }
Render Items
The render function determines the subset of cards to be displayed and populates the array with images and alt strings.
- <dx-pagination ... ></dx-pagination>
- <div id="cards">
- <ng-container *ngFor="let color of visibleCards">
- <img [src]="color.image" [alt]="color.name" />
- </ng-container>
- </div>
- import { Component } from '@angular/core';
- import { firstValueFrom } from 'rxjs';
- import { ColorService, Color } from './app.service';
- @Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css'],
- providers: [ColorService],
- })
- export class AppComponent {
- // ...
- colors: Map<string, Color> = new Map();
- visibleCards: Color[] = [];
- constructor(private readonly colorService: ColorService) {}
- ngOnInit(): void {
- // ...
- void this.fetchColorsForPage();
- }
- async fetchColorsForPage(): Promise<void> {
- const startIndex = (this.pageIndex - 1) * this.pageSize;
- const endIndex = this.pageIndex * this.pageSize;
- const hexSubset = this.hexCodes.slice(startIndex, endIndex);
- const promises: Promise<Color>[] = hexSubset.map((hex) => {
- if (this.colors.has(hex)) {
- return Promise.resolve(this.colors.get(hex)!);
- } else {
- return firstValueFrom(this.colorService.fetchColorData(hex)).then((data) => {
- const colorData: Color = data;
- this.colors.set(hex, colorData);
- return colorData;
- });
- }
- });
- try {
- const fetchedColors = await Promise.all(promises);
- this.visibleCards = fetchedColors;
- } catch (error) {
- console.error('Error fetching colors:', error);
- }
- }
- }
- // ...
- export interface Color {
- image: string;
- name: string;
- }
- #cards {
- display: flex;
- justify-content: center;
- flex-wrap: wrap;
- }
Handle Page Size and Index Changes
The render function is called on every page index/size change:
- <dx-pagination ...
- (pageIndexChange)="onPageIndexChange($event)"
- (pageSizeChange)="onPageSizeChange($event)"
- >
- </dx-pagination>
- <!-- ... -->
- // ...
- export class AppComponent {
- // ...
- onPageIndexChange(val: number): void {
- this.pageIndex = val;
- void this.fetchColorsForPage();
- }
- onPageSizeChange(val: number): void {
- this.pageSize = val;
- void this.fetchColorsForPage();
- }
- }
Integrate LoadPanel
The following code integrate a load panel into the application. The panel appears when the app requests card data from the remote service. This step is optional.
To integrate the DevExtreme LoadPanel component:
- Add a LoadPanel to the code.
- Display it before calling the render function.
- Hide it after render.
- <dx-pagination ... ></dx-pagination>
- <!-- ... -->
- <dx-load-panel
- [(visible)]="loadPanelVisible"
- [showIndicator]="true"
- [showPane]="true"
- [hideOnOutsideClick]="false"
- >
- <dxo-position my="top" at="top" of="#cards"></dxo-position>
- </dx-load-panel>
- // ...
- export class AppComponent {
- // ...
- loadPanelVisible = false;
- async fetchColorsForPage(): Promise<void> {
- const startIndex = (this.pageIndex - 1) * this.pageSize;
- const endIndex = this.pageIndex * this.pageSize;
- const hexSubset = this.hexCodes.slice(startIndex, endIndex);
- const promises: Promise<Color>[] = hexSubset.map((hex) => {
- // ...
- });
- this.loadPanelVisible = true;
- try {
- const fetchedColors = await Promise.all(promises);
- this.visibleCards = fetchedColors;
- } catch (error) {
- console.error('Error fetching colors:', error);
- } finally {
- this.loadPanelVisible = false;
- }
- }
- }
If you have technical questions, please create a support ticket in the DevExpress Support Center.