12

I have use Angular Material table, i have bind data source from ts file,but all the data is loaded on very first page, pagination is not working.I have two more table, which are on same page,same problem for other tables too.

I have tried

setTimeout(() => this.dataSource.paginator = this.paginator);

and

ngAfterViewInit() {
   this.dataSource.paginator = this.paginator
}

HTML:

    <mat-table class="mt-4 table-container" fxFlex="100" [dataSource]="allUsers">
      <ng-container matColumnDef="checked">
        <mat-header-cell fxFlex="10" (click)="selectAllUsers()" *matHeaderCellDef>
          <mat-checkbox [(ngModel)]="checkedAllUsers"></mat-checkbox>
        </mat-header-cell>
        <mat-cell fxFlex="10" *matCellDef="let element">
          <mat-checkbox [(ngModel)]="element.checked"></mat-checkbox>
        </mat-cell>
      </ng-container>

      <ng-container matColumnDef="firstName">
        <mat-header-cell fxFlex="25" *matHeaderCellDef> First Name </mat-header-cell>
        <mat-cell fxFlex="25" *matCellDef="let element"> {{element.firstName}} </mat-cell>
      </ng-container>

      <ng-container matColumnDef="lastName">
        <mat-header-cell fxFlex="25" *matHeaderCellDef> Last Name </mat-header-cell>
        <mat-cell fxFlex="25" *matCellDef="let element"> {{element.lastName}} </mat-cell>
      </ng-container>

      <ng-container matColumnDef="email">
        <mat-header-cell fxFlex="30" *matHeaderCellDef> Email </mat-header-cell>
        <mat-cell fxFlex="30" *matCellDef="let element"> {{element.email}} </mat-cell>
      </ng-container>

      <ng-container matColumnDef="actions">
        <mat-header-cell fxFlex="10" *matHeaderCellDef> Action </mat-header-cell>
        <mat-cell fxFlex="10" *matCellDef="let row; let i=index;">
          <button mat-icon-button class="viewButton" (click)="view(i, row.id, row.title, row.state, row.url, row.created_at, row.updated_at)">
            <mat-icon aria-label="Delete">remove_red_eye</mat-icon>
          </button>
        </mat-cell>
      </ng-container>
      <mat-header-row *matHeaderRowDef="allUsersColumns"></mat-header-row>
      <mat-row *matRowDef="let row; columns: allUsersColumns;"></mat-row>
    </mat-table>
    <mat-paginator #allUsersPaginatorr [pageSizeOptions]="[10,20,30]" showFirstLastButtons></mat-paginator>

TS Code:

 @ViewChild(MatPaginator) paginator: MatPaginator;

 allUsersColumns: string[] = ['checked', 'firstName', 'lastName', 'email', 
'actions'];
allUsersDataSource = new MatTableDataSource<any>();
 allUsers: any[] = [
{ checked: false, firstName: 'Debi', lastName: 'Austin', email: 
 'd@gmail.com' },
  { checked: false, firstName: 'Jimmy', lastName: 'Williams', email: 
 'w@yahoo.in' },
  { checked: false, firstName: 'Randy', lastName: 'Waif', email: 
 'randy@gmail.com' },
  { checked: true, firstName: 'Chad', lastName: 'Spongla', email: 
   'c@redif.com' },
   { checked: false, firstName: 'Debi', lastName: 'Austin', email: 
  'd@gmail.com' },
  { checked: false, firstName: 'Jimmy', lastName: 'Williams', email: 
  'w@yahoo.in' },
  { checked: false, firstName: 'Randy', lastName: 'Waif', email: 
  'randy@gmail.com' },
  { checked: false, firstName: 'Chad', lastName: 'Spongla', email: 
 'c@redif.com' },
  { checked: false, firstName: 'Debi', lastName: 'Austin', email: 
 'd@gmail.com' },
    { checked: true, firstName: 'Jimmy', lastName: 'Williams', email: 
 'w@yahoo.in' },
  { checked: false, firstName: 'Chad', lastName: 'Spongla', email: 
 'c@redif.com' },
  { checked: false, firstName: 'Debi', lastName: 'Austin', email: 
 'd@gmail.com' },
  { checked: true, firstName: 'Jimmy', lastName: 'Williams', email: 
 'w@yahoo.in' }
 ];
ngOnInit() {
 this.allUsersDataSource = new MatTableDataSource(this.allUsers);
  this.allUsersDataSource.paginator = this.paginator;
}
Prashant Pimpale
  • 10,349
  • 9
  • 44
  • 84
Jayant Belekar
  • 243
  • 1
  • 3
  • 9

6 Answers6

19

If your mat-paginator is inside any ngIf conditioned block as shown in the below code, then the table shows all the data in the first page itself.

<div *ngIf="isDataLoaded">
   <mat-table [dataSource]="dataSource">
      ...
      ...
   </mat-table>
   <mat-paginator
         [length]="allUsers.length"
         [pageSize]="5"
         [pageSizeOptions]="[5, 10, 20]">
   </mat-paginator>
</div>

Solution 1: Move the mat-paginator code block outside of the ngIf conditioned block as shown below:

<div *ngIf="isDataLoaded">
   <mat-table [dataSource]="dataSource">
      ...
      ...
   </mat-table>
</div>
<mat-paginator
         [length]="allUsers.length"
         [pageSize]="5"
         [pageSizeOptions]="[5, 10, 20]">
</mat-paginator>

Solution 2: Use hidden as alternative for ngIf directive as shown below:

<div [hidden]="!isDataLoaded">
   <mat-table [dataSource]="dataSource">
      ...
      ...
   </mat-table>
   <mat-paginator
         [length]="allUsers.length"
         [pageSize]="5"
         [pageSizeOptions]="[5, 10, 20]">
   </mat-paginator>
</div>

Note: And of course, following mandatory steps for initializing mat-table data and mat-paginator

this.dataSource = new MatTableDataSource(this.allUsers);
this.dataSource.paginator = this.paginator;

Happy Coding...Cheerzz

Darshuu
  • 501
  • 5
  • 9
8

You should assign your data to the this.allUsersDataSource.data. Also ngAfterViewInit is necessary to relate the paginator with the table. Change your code

ngOnInit() {
 this.allUsersDataSource = new MatTableDataSource(this.allUsers);
  this.allUsersDataSource.paginator = this.paginator;
}

with

ngOnInit() {
     this.allUsersDataSource.data = new MatTableDataSource(this.allUsers);
}
ngAfterViewInit() {
      this.allUsersDataSource.paginator = this.paginator;
}
boyukbas
  • 1,137
  • 16
  • 24
3

The data source for the table should be allUsersDataSource not allUsers.

So change:

<mat-table class="mt-4 table-container" fxFlex="100" [dataSource]="allUsers">
                                                                     /\

To,

<mat-table class="mt-4 table-container" fxFlex="100" [dataSource]="allUsersDataSource">

Stackblitz

Prashant Pimpale
  • 10,349
  • 9
  • 44
  • 84
1

My problem was that the paginator was inside a div block with ngIf depending on the dataSource. So when in ngAfterViewInit() I call this.dataSource.paginator = this.paginator; this.paginator is not initialised. In my case the dataSource is initialised after the ngAfterViewInit is called due to the backend response time. The solution was to change ngIf with [hidden]. In that case the table and the paginator are not shown when there is no data, but this.paginator is initialised, so when the data comes in it will be set to the data dource properly.

0

You should to initialize paginator like this:

@ViewChild(MatPaginator, {static: true}) set matPaginator(paginator: MatPaginator) {
    this.dataSource.paginator = paginator;
}
youri
  • 3,685
  • 5
  • 23
  • 43
0

Use mat-table inside its own component, with ngAfterViewInit defined such as

@Component({
  selector: 'app-topics',
  templateUrl: './topics.component.html',
  styleUrls: ['./topics.component.scss']
})
export class TopicsComponent implements OnInit {
  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;


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

You can embed the mat-table component in the parent template (in this example with lazy loading) such as

<ng-template matExpansionPanelContent>
    <app-topics> </app-topics>
</ng-template>
Sri
  • 39
  • 1
  • 1