How to set the length prop for the angular material paginator
Asked Answered
G

3

8

This is what my mat-paginator looks like:

<mat-paginator [pageSizeOptions]="pageSizeOptions" [length]="100"></mat-paginator>

Basically I'm trying to implement a typical pagination idea: the server does not return all the data, it returns a chunk of it and then when a new page is opened it goes for another fraction of data. In order to do that, I need to let the paginator know how many items are there in the database, that's to say, I need to provide it with the length prop.

I tried setting it in a variety of ways, directly like in the line above or inside the method where I make a get request. Like this:

this.paginator.length = 100;

Indeed the length should come from the server but for the time being for debug purposes I simply hardcode it.

    this.dataSourceService.findAll().subscribe(
      records => {
        this.paginator.length = 100;

        this.dataSource.data = records.map(
          record => new Record().deserialize(record)
        )
      }
    )

Still the length value I get on the client is equal to the number of items contained in the array I get in the server response.

What am I doing wrong and why the length value is not set to 100.

EDIT:

Alright, here is some more relevant code.

Inside the component I do the following:

dataSource = new MatTableDataSource<Record>();
pageSizeOptions: number[] = [5, 10, 20];

inside the OnInit() I also have the following line: this.dataSource.paginator = this.paginator;

Goldarn answered 5/1, 2020 at 15:38 Comment(1)
Post the relevant code. Currently, the only thing we can see about your code is that you have [length]="100". We have no idea of what paginator is, how it's used, etc. Stackblitz is your friend.Ladanum
S
3

I'm using it like this

<mat-paginator
          [pageSize]="pageSize"
          [pageIndex]="pageNumber-1"
          [pageSizeOptions]="[10, 25, 50, 100]"
          [length]="itemCount"
          (page)="changePaging($event)"
>

lets say that the return of your observable is an object { list: [], count: xx } count is the total items (without pagination)

this.list$ = this.dataSourceService
      .findAll()
      .pipe(tap(r => (this.itemCount = r.count)));

of course you can subscribe after that for more actions...

check the docs also https://material.angular.io/components/paginator/api

Scutch answered 5/1, 2020 at 15:56 Comment(0)
C
13

For other people walking into the same problem as me:

If you have your dataSource connected to your paginator, it will overwrite any values you set.

Remove this:


this.dataSource.paginator = this.paginator;

Claro answered 7/11, 2022 at 20:21 Comment(1)
Thanks, this is poorly documented :-(Adamantine
S
3

I'm using it like this

<mat-paginator
          [pageSize]="pageSize"
          [pageIndex]="pageNumber-1"
          [pageSizeOptions]="[10, 25, 50, 100]"
          [length]="itemCount"
          (page)="changePaging($event)"
>

lets say that the return of your observable is an object { list: [], count: xx } count is the total items (without pagination)

this.list$ = this.dataSourceService
      .findAll()
      .pipe(tap(r => (this.itemCount = r.count)));

of course you can subscribe after that for more actions...

check the docs also https://material.angular.io/components/paginator/api

Scutch answered 5/1, 2020 at 15:56 Comment(0)
B
0

@Neter's answer seemed to only work if I did what @moffeltje proposed, however, it created another problem for me and that was the disconnection between the table and the paginator.
Removing this line:

this.dataSource.paginator = this.paginator;

Meant my paginator was now disconnected (next button had no effect on existing table data).

I resolved it by wrapping it in a timeless timeout:

this.paginatorLength = 100;
setTimeout(() => {
    // this.paginatorLength can be replaced by a local variable set with whatever you use to tell the length of all data entires (I.e db counts).
    this.dataSource.paginator.length = this.paginatorLength;
});

The thinking here is that if it's doing the overwrite, and it is (see @moffeltje answer), that will happen at the same "tick" or scope of execution that the overwrite happened. If we can do the set after the "writing" has happened, including any events within the Material Lib, then it can't be overwritten since now it's doing the overwrite.

Use with caution: I strongly recommend that you don't commonly practise setTimeout development as it can make your code obscure and difficult to debug. Please place your timeouts at the end of your method/function and add comments explaining why it's there.

Blackamoor answered 24/5, 2024 at 5:1 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.