Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Material Paginator

Tags:

angular

I'm gonna be very specific with my question, hoping for an equally specific answer.

I've combed online, and the Angular docs on the subject is as vague for real life cases as asking you to pick a needle from the ocean. Ooh Angular docs...

What I have done so far

  <mat-paginator (page)="pageEvent = $event" #paginator [length]="pageLength" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions">
  </mat-paginator>

And this in my component

  pageLength: number;
  pageSize: 5;
  pageSizeOptions = [5, 10, 25, 100];

and then I update the pageLength when the endpoint response is in like so:

  loadRequests() {
    this.busy = true;
    this.request_service.get_requests()
      .subscribe((res) => {
        console.log(res);
        this.requests = res['requests'];
        this.pageLength = this.requests.length; // let's assume length = 1000
      });
  }

The above renders renders the UI for the pagination nicely in the browser

The endpoint being consumed via .get_requests(), for the sake of simplicity, returns only 1000 fixed items.

Now, this is how I'm rendering my list at the moment:

<mat-card *ngFor="let request of requests">
  <mat-card-title> {{ request.title }}</mat-card-title>
</mat-card>

So with the above preamble, what steps are my left to complete to get pagination to work with this condition in mind:

  • The pagination doesn't keep going to endpoint to pull each list of items for each pageIndex.
  • After receiving the 1000 items at first hit from the endpoint, then pagination chunks this length of items up locally on the client side. No more API calls.
like image 636
KhoPhi Avatar asked Aug 07 '18 23:08

KhoPhi


People also ask

What is Paginator Angular?

The paginator displays a dropdown of page sizes for the user to choose from. The options for this dropdown can be set via pageSizeOptions. The current pageSize will always appear in the dropdown, even if it is not included in pageSizeOptions.

How do you get the current page number in pagination Angular material?

You can get the current page index by using the page Output event. The $event from page returns three pieces of information: pageIndex. pageSize.

How do I change the page size on a mat-Paginator label?

The labels for the paginator can be customized by providing your own instance of MatPaginatorIntl . This will allow you to change the following: The label for the length of each page. The range text displayed to the user.


2 Answers

Let's assume you've loaded the response data (Array) in requests .

You can probably create a method that returns a set of data from the requests property using the splice method.

Therefore, on the API subscribe results, it can be handled like this for the first time load:

this.request_service.get_requests()
  .subscribe((res) => {
    this.pageLength = res['requests'].length;
    this.splicedData = res['requests'].slice(((0 + 1) - 1) * this.pageSize).slice(0, this.pageSize);
  });

where pageSize, has been defined in earlier on to a default value.

Then, anytime the user changes the mat-paginator component in the template, the pageChangeEvent is run. Template looks like this:

  <mat-paginator (page)="pageChangeEvent($event)" [length]="pageLength" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions">
  </mat-paginator>

Then its corresponding component method is this.

 pageChangeEvent(event) {
    const offset = ((event.pageIndex + 1) - 1) * event.pageSize;
    this.splicedData = this.requests.slice(offset).slice(0, event.pageSize);
  }

Finally, your *ngFor can use the splicedData array to populate itself.

<mat-card *ngFor="let request of splicedData">
    <mat-card-title> {{ request.title }}</mat-card-title>
</mat-card>
like image 152
PRAKASH THOMAS VARGHESE Avatar answered Oct 02 '22 09:10

PRAKASH THOMAS VARGHESE


You could use the mat-table, it integrates very well with the mat-paginator. Hiding the header and changing the style to make it look the way you want.

The component :

displayedColumns: string[] = ['requests'];
dataSource: MatTableDataSource<{request: number}>;
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;

constructor() {
 this.dataSource = new MatTableDataSource(values);
}

ngOnInit() {
 this.dataSource.paginator = this.paginator;
 this.dataSource.sort = this.sort;
}

The template :

<table mat-table [dataSource]="dataSource" matSort>

 <!-- Requests Column -->
   <ng-container matColumnDef="requests">
     <th mat-header-cell *matHeaderCellDef mat-sort-header/>
     <td mat-cell *matCellDef="let row"> {{row.request.title}} </td>
   </ng-container>

   <tr mat-header-row *matHeaderRowDef="displayedColumns"/>
   <tr mat-row *matRowDef="let row; columns: displayedColumns;">
   </tr>
</table>

<mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"/>

Here is a running example.

like image 32
ibenjelloun Avatar answered Oct 02 '22 09:10

ibenjelloun