Call the API with pagination parameters
Create a new interface models/Pagination to store the pagination info received in the headers with the same properties of PaginationHeader.cs
export interface Pagination {
currentPage: number;
itemsPerPage: number;
totalItems: number;
totalPages: number;
}
Create a new class models/PaginatedResult to store the paginated data and the pagination info.
export class PaginatedResult<T> {
result: T;
pagination: Pagination;
}
Modify user.service.ts method getUsers to accept optional pagination parameters and put them in the query string. Then map the resulting User[ ] in a PaginatedResult
getUsers(
page?: string,
itemsPerPage?: string
): Observable<PaginatedResult<User[]>> {
let params = new HttpParams();
if (page != null && itemsPerPage != null) {
params = params.append('pageNumber', page);
params = params.append('pageSize', itemsPerPage);
}
return this.http
.get<User[]>(this.baseUrl, {
params: params,
observe: 'response'
})
.pipe(
map(response => {
const paginatedResults = new PaginatedResult<User[]>();
paginatedResults.result = response.body;
if (response.headers.get('Pagination') != null) {
paginatedResults.pagination = JSON.parse(
response.headers.get('Pagination')
);
}
return paginatedResults;
})
)
.pipe(catchError(this.handleError));
}
Fix member-list.resolver.ts to make use of the Observable<PaginatedResult
// ...
pageNumber = 1;
pageSize = 5;
// ...
resolve(route: ActivatedRouteSnapshot): Observable<PaginatedResult<User[]>> {
return this.userService.getUsers(this.pageNumber, this.pageSize).pipe(
catchError(error => {
this.alertify.error('Problem retrieving data');
this.router.navigate(['/home']);
return empty();
})
);
}
// ...
Finally in member-list.component.ts use the new PaginatedResult
ngOnInit() {
this.route.data.subscribe(data => {
this.users = data['users'].result;
});
}
Test the application
Navigate to Matches, verify that only the first 5 users are visible.
ngx-bootstrap pagination
To handle the pagination we use the Valorsoft ngx bootstrap pagination
Register the component in the imports section of app.module.ts
PaginationModule.forRoot(),
Open member-list.component.html and add the code from the section Custom links content
<div class="container">
<div class="row">
<div *ngFor="let user of users" class="col-lg-2 col-md-3 col-sm-6">
<app-member-card [user]="user"></app-member-card>
</div>
</div>
</div>
<div class="text-center">
<pagination [boundaryLinks]="true" [totalItems]="77" previousText="‹" nextText="›" firstText="«" lastText="»">
</pagination>
</div>
Open member-list.component.ts and add a property for the Pagination object.
// ...
pagination: Pagination;
// ...
ngOnInit() {
this.route.data.subscribe(data => {
this.users = data['users'].result;
this.pagination = data['users'].pagination;
});
}
// ...
Back in the html bind the pagination property to the attributes of the pagination element
<pagination [boundaryLinks]="true" [totalItems]="pagination.totalItems" [itemsPerPage]="pagination.itemsPerPage"
[(ngModel)]="pagination.currentPage" (pageChanged)="pageChanged($event)"
previousText="‹" nextText="›" firstText="«" lastText="»">
</pagination>
Now create the pageChanged method and restore the loadUsers method with the new pagination features
pageChanged(event: any): void {
this.pagination.currentPage = event.page;
this.loadUsers()
}
loadUsers() {
this.userService.getUsers(this.pagination.currentPage, this.pagination.itemsPerPage).subscribe(
result => {
this.users = result.result;
this.pagination = result.pagination;
},
error => {
this.alertify.error(error);
}
);
}