here i have a issue while working with angular paginator. here i am getting data like below
Response One:
{
"Tabledata": [
{
"firstName":"Samuel",
"lastName":"Smith"
},
{
"firstName":"Sanu",
"lastName":"Smith"
}
],
"paging": {
"RecordsCount": 2,
"token": "JhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
}
}
Response Two: I am getting total records count as 50
{
'RecordsCount' : 50
}
Now in the initial call the i am calling api and the api format is below
Initial Call
http://some api.com/data?searchParams=&pageSize=2&token=
After calling this i will get response like below
{
"Tabledata": [
{
"firstName":"Samuel",
"lastName":"Smith"
},
{
"firstName":"Sanu",
"lastName":"Smith"
}
],
"paging": {
"RecordsCount": 2,
"token": "JhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
}
}
and after pressing the next button the api should initiate another http call and use this token and send it params for the same api like below
2nd call
http://some api.com/data?searchParams=&pageSize=2&token=JhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
After this call i will get again same response but here token changes
{
"Tabledata": [
{
"firstName":"Samuel",
"lastName":"Smith"
},
{
"firstName":"Sanu",
"lastName":"Smith"
}
],
"paging": {
"RecordsCount": 2,
"token": "abcd"
}
}
And if i press next again in the 3rd api call is should use the 2nd response token as param for the 3rd call and it will give some token and if user presses Prev then it should use that tocken and send as param here this i am unable to solve this in front end i wrote like
<mat-paginator [pageSize]="10" [length]="totalLength" [pageSizeOptions]="[5, 10, 25, 100]" (page)="PageEvents($event)"></mat-paginator>
PageEvents(event: PageEvent){
this.pageNumber = 1;
const pageSize = +event.pageSize;
const currentPage = +event.pageIndex + 1;
const pagination = {
searchQuery: '',
pageSize: pageSize,
token: ''
};
if(currentPage > this.pageNumber) {
console.log('next button',pageSize,currentPage)
} else {
console.log('prev button',pageSize,currentPage)
}
}
totalLength= 50
here my issues
<mat-paginator
[length]="total"
[pageSize]="pageSize"
[pageSizeOptions]="pageSizeOptions"
[showFirstLastButtons]="isShowFirstLastBtn"
(page)="onChangePage($event)"
></mat-paginator>
Then in your component file, you can receive the page event as:
private subscription = new Subscription();
ngOnInIt() {
// subscribe to the service for page data
this.subscription = this.service.tableDataAction$.subscribe(resp => do initial table render);
}
onChangePage(event: PageEvent) {
const pageSize = +event.pageSize; // get the pageSize
const currentPage = +event.pageIndex + 1; // get the current page
this.service.paginationData(pageSize, currentPage); // call the service
}
ngOnDestroy() {
this.subscription.unsubscribe()
}
in service:
private paginationSubject = new Subject<{}>();
tableDataAction$ = this.paginationSubject.asObservable();
paginationData(pageSize: number, currentPage: number) {
// get or post whatever you prefer, get is more correct choice
this.http.get(url + queryParams).subscribe(
(resp) => this.paginationSubject.next(resp)),
(err) => catchError // handle error
}
PS: To get total count of pagination you should also sent the total Count of the data present with the current data so that in pagination you can show item n of total
First of all, It is recommended to avoid using a token for pagination. You can simply use skip
and limit
. Something that you are currently using is pageSize
which works as limit and let us call a new param currentPage
as skip. Anyways moving ahead with token, the implementation logic is as below.
Step 1
You will need following member variables for component in which paginator is present.
defaultPayload = {
searchParams : "",
pageSize : 2,
currentPage : 1,
token : ""
};
totalLength = 0;
the defaultPayload
is argument to your service through which new data comes in. You need currentPage
at angular service level for tokenMap
implementation will explain in sometime. totalLength
as you have already binded it to mat-paginator.
Before moving ahead, you have a question about totalLength
. As shown in image your totalLength is 2, As the pageSize
is 10, the functionality of next and previous are disabled. It makes sense too. If your response RecordsCount
is 50, it will show up if you have set the member variable as the following step demonstrates.
Step 2 On load
Let's say we are subscribed to the api service as below in ngInit
ngOnInit() {
this.getDataService(this.defaultPayload)
.subscribe(
res => {
this.defaultPayload.token = paging['token'];
this.totalLength = paging['RecordsCount'];
},
err => {}
);
}
On response, we are:
RecordsCount
in totalLength (which you might be expecting 50, but its 2)Step 3 On event
PageEvents(event){
console.log("event", event, this.defaultPayload);
const pageSize = event.pageSize;
const currentPage = event.pageIndex + 1;
this.defaultPayload.pageSize = pageSize;
this.defaultPayload.currentPage = currentPage;
this.getDataService(this.defaultPayload)
}
Note We are just resetting our request payload again as per new event and make a service call.
Step 4 Service
let say we have some service as follows that is responsible for providing data. We need to maintain some kind of storage for token. you might use localstorage or simply an object as below whatever suits your need. This is needed because we need to maintain tokens for all (old) prev and (new) next page events.
constructor() {
this.tokenMap = {};
}
getDataService({...options, currentPage}){
options.token = findToken(currentPage)
//http request using {options}
//on response setToken
this.setTokenMap(options.currentPage, response['token])
return responseData
}
findToken(page){
return this.tokenMap[page || 1] || "";
}
setTokenMap(page, token){
this.tokenMap[page] = token;
}
This service will find the token while making an api call, and also set the new token as per currentPage, hence you don't have to bother about token in component. This will separate your concerns of the token logic and component paginator data.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.