This is my way of solving all these problems.
1: Make sure that the Backend (API) has cors enabled to show the client the "X-Pagination" header like this:
app.UseCors(builder => builder.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().WithExposedHeaders(new string[] { "X-Pagination"}));
2: HTML:
<ng2-smart-table [settings]="settings" [source]="source"></ng2-smart-table>
3: SERVICE:
getClients(pageNumber: number, pageSize: number): Observable<any> {
const headers = new HttpHeaders({'Content-Type': 'application/json','Accept': 'application/json' });
let params = new HttpParams();
params = params.append('PageNumber',pageNumber.toString());
params = params.append('PageSize',pageSize.toString());
return this.http.get<ClientDto[]>(API_URL, {headers: headers, observe: "response" as "body", responseType: "json", params} );
}
4: TS:
export class ListClientComponent implements OnInit {
source: LocalDataSource;
pageSize = 30;
currentPage = 1;
showPerPage = 10;
totalCount;
constructor(private service: ClientService,private router: Router) {
this.initData();
}
public settings = {
mode: 'external',
pager:{
display: true,
perPage: this.showPerPage,
},
actions: {
add:false,
edit:true,
delete:false
},
columns: {
clientId: {
title: 'CI',
},
name: {
title: 'Name'
},
instagramName: {
title: 'Instagram'
},
type: {
title: 'Type'
},
phone: {
title: 'Phone'
},
gender: {
title: 'Gender'
},
age: {
title: 'Age'
},
city: {
title: 'City'
},
email: {
title: 'Email'
}
},
};
ngOnInit() {
this.initOnChagedData();
}
onEdit(event){
console.log(event.data.clientId);
this.router.navigate(['/clients/update-client/'+ event.data.clientId]) ;
}
initData(){
this.source = new LocalDataSource();
this.service.getClients(this.currentPage, this.pageSize).subscribe( (result: HttpResponse<any>) => {
if(!result){
return;
}
this.source.load(result.body);
this.totalCount = JSON.parse(result.headers.get("X-Pagination"));
this.totalCount = this.totalCount["totalCount"];
console.log(this.source.count());
}
)
}
initOnChagedData(){
this.source.onChanged().subscribe((change) => {
if (change.action === 'page') {
this.pageChange(change.paging.page);
}
});
}
pageChange(pageIndex) {
var getNew = pageIndex * this.showPerPage;
if( getNew >= this.source.count() && getNew < this.totalCount){
this.currentPage = this.currentPage + 1;
this.service.getClients(this.currentPage, this.pageSize).subscribe( result => {
if(!result){
return;
}
result.body.forEach(element => {
this.source.add(element);
});
})
}
}
}
You should notice that pageSize = total data that we extract from the backend
and show per page = total data that we show in the table.
The algorithm is designed to extract from the API only when necessary, that is, when the client reaches a page where the data ends in memory, then it asks for 30 more data to have another 3 pages, and also does not forget the other 3 that already had extracted before.