I implemented the server side pagination in angular and it is working fine, the problem is the page I set initially on 1 , but the mat-paginator starts at index 2. When I change pages it works fine, I`d like to know how to solve this bug.
This is the paginate method in nodejs:
paginate() {
const page = this.queryString.page * 1 || 1
const limit = this.queryString.limit * 1 || 100
const skip = (page - 1) * limit
this.query = this.query.skip(skip).limit(limit)
return this
}
This is the component:
import { Component } from '@angular/core'
import { Equipment } from '../../models/equipment.model'
import { DialogService } from 'src/app/shared/services/dialog.service'
import { Store } from '@ngrx/store'
import {
getEquipments,
getEquipmentsCount,
getIsLoading,
State
} from '../../state'
import { Observable } from 'rxjs'
import { EquipmentPageActions } from '../../state/actions'
import { PageEvent } from '@angular/material/paginator'
@Component({
selector: 'app-equipments-list',
templateUrl: './equipments-list.component.html',
styleUrls: ['./equipments-list.component.css']
})
export class EquipmentsListComponent {
isLoading$: Observable<boolean>
equipments$: Observable<Equipment[]>
count$: Observable<number>
page = 1
pageSize = 3
constructor(
private dialogService: DialogService,
private store: Store<State>
) {}
ngOnInit(): void {
this.store.dispatch(
EquipmentPageActions.loadEquipments({
page: this.page,
limit: this.pageSize
})
)
this.equipments$ = this.store.select(getEquipments)
this.isLoading$ = this.store.select(getIsLoading)
this.count$ = this.store.select(getEquipmentsCount)
}
onDeleteEquipment(id: string): void {
this.dialogService
.confirmDialog({
title: 'DELETE EQUIPMENT',
message: 'Are you sure you want to delete?',
confirmText: 'No',
cancelText: 'Yes'
})
.subscribe((confirm) => {
if (confirm) {
this.store.dispatch(
EquipmentPageActions.deleteEquipment({ id })
)
}
})
}
handlePageChange(pageEvent: PageEvent): void {
this.page = pageEvent.pageIndex
this.pageSize = pageEvent.pageSize
this.store.dispatch(
EquipmentPageActions.loadEquipments({
page: this.page + 1,
limit: this.pageSize
})
)
}
}
This is the template:
<div
class="d-flex flex-column align-items-center justify-content-center h-100"
*ngIf="isLoading$ | async"
>
<div class="spinner-border" role="status">
<span>Loading...</span>
</div>
</div>
<div class="container" *ngIf="!(isLoading$ | async)">
<div class="row">
<div class="col-xs-12">
<h1 class="fw-bold text-center">Equipments</h1>
<div class="mb-2">
<a
class="btn btn-primary btn-sm"
type="button"
[routerLink]="'add'"
>Add</a
>
</div>
<table class="table shadow-lg table-responsive">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Power</th>
<th scope="col">Installation</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody *ngIf="equipments$ | async as equipments">
<tr scope="row" *ngFor="let equip of equipments">
<td>{{ equip.name }}</td>
<td>{{ equip.powerRequirement }}</td>
<td class="text-nowrap">
{{ equip.installationDate | date : 'dd-MM-yyyy' }}
</td>
<td class="text-nowrap">
<button
class="btn btn-secondary btn-sm me-1"
[routerLink]="[equip._id]"
>
View
</button>
<a
class="btn btn-primary btn-sm me-1"
type="button"
[routerLink]="[equip._id + '/edit']"
>Edit</a
>
<button
class="btn btn-danger btn-sm"
type="button"
(click)="onDeleteEquipment(equip._id)"
>
Delete
</button>
</td>
</tr>
</tbody>
</table>
<div class="text-center" *ngIf="equipments$ | async as equipments">
<p *ngIf="equipments.length === 0">No equipments</p>
</div>
<mat-paginator
[length]="count$ | async"
[pageSize]="pageSize"
[pageSizeOptions]="[3, 6, 9]"
[showFirstLastButtons]="true"
[pageIndex]="page"
(page)="handlePageChange($event)"
>
</mat-paginator>
</div>
</div>
</div>
Any idea where I am missing the problem?
initially the handlePageChange was :
handlePageChange(pageEvent: PageEvent): void {
this.page = pageEvent.pageIndex
this.pageSize = pageEvent.pageSize
this.store.dispatch(
EquipmentPageActions.loadEquipments({
page: this.page,
limit: this.pageSize
})
)
}
And the page would start at 1 but resulted for the server as 0 so everything was loaded. Then I added + 1 to the this.pageSize = pageEvent.pageSize , so I got the page 2 loaded, but when I go on page 1 works fine.
I`ve managed to sort the problem adding + 1 to the page in the ngOnInit
ngOnInit(): void {
this.store.dispatch(
EquipmentPageActions.loadEquipments({
page: this.page + 1,
limit: this.pageSize
})
)
this.equipments$ = this.store.select(getEquipments)
this.isLoading$ = this.store.select(getIsLoading)
this.count$ = this.store.select(getEquipmentsCount)
}