I'm trying to implement an Angular material table with pagination, that is connected to the backend, that retrieves data from Azure Table Storage.
I know, that Table Storage supports ExecuteQuerySegmentedAsync, which returns TableContinuationToken. It looks fine. So on the frontend, I get something like this:
interface IPagedResult<T> {
items: T[];
isFinalPage: boolean;
continuationToken: string;
}
interface ILog {
enqueuedDate: string;
...
}
Somewhere in component.ts:
private logsTableSource: MatTableDataSource<ILog>;
@ViewChild(MatPaginator)paginator: MatPaginator;
ngAfterViewInit() {
myService.GetRecords(this.paginator.pageSize)
.subscribe(
(res: IPagedResult<ILog>) => {
this.logsTableSource = new MatTableDataSource<ILog>(res.items);
});
}
Now I'm wondering, how to get the number of pages? And let the server know what specific page I want?
continuationToken
looks like this:
In fact, what I can do with this continuationToken?
As @rickvdbosch said, TableContinuationToken
expects only moving forward. After some changes in the paginator I can move only forward and backward. Looks quite good and works for me:
If someone is interested. Here are the changes:
MatPaginatorIntl
to remove pages label. My looks like this:@Injectable()
export class LogsPaginator extends MatPaginatorIntl {
public getRangeLabel = function (page: number, pageSize: number, length: number) {
return '';
};
}
export class LogsComponent {
// As table storage does not support paging per index, we should cache already loaded logs and use continuation token if needed.
private cachedLogs: ILog[] = [];
private cachedIndexes: number[] = [];
private continuationToken = '';
ngOnInit() {
this.paginator.page.subscribe(this.pageChanged.bind(this));
}
async ngAfterViewInit() {
await this.loadLogs();
}
private async pageChanged(event: PageEvent) {
if (event.previousPageIndex < event.pageIndex && this.cachedIndexes.indexOf(event.pageIndex) === -1) {
await this.loadLogs();
} else {
this.redrawTable();
}
}
private redrawTable() {
const start = this.paginator.pageIndex * this.paginator.pageSize;
const end = start + this.paginator.pageSize;
this.logsTableSource.data = this.cachedLogs.slice(start, end);
}
private async loadLogs() {
const res = await this.myService.GetLogs(this.paginator.pageSize, this.continuationToken).toPromise();
this.cachedIndexes.push(this.paginator.pageIndex);
this.cachedLogs.push(...res.items);
this.paginator.length = res.isFinalPage ? this.cachedLogs.length : this.cachedLogs.length + 1;
this.continuationToken = res.continuationToken;
this.redrawTable();
}
}