Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to attach MatPaginator to datasource coming from server in angular material table?

I am using angular Material table to create grid in my Angular 5 project. My data is coming from http request and its assigned to a variable called dataSourceNew like this in view.ts file. Here dataSourceNew has dynamic content and strucuture and so I am not exporting any interface.

      this.http.get('http://example.org?,{headers: this.headers})
          .subscribe(
          res => { 

           this.displayedColumnsNew = res.record;
           this.dataSourceNew = res.data;
           this.matdatasource = new MatTableDataSource(this.dataSourceNew);
           this.dataSourceNew.paginator = this.paginator;
           console.log("got matdatasource object",this.matdatasource);
      // attached the result of this log below

         });

I am successfully able to create a data-table using this syntax in html file.

     <div class="example-container mat-elevation-z8">
           <mat-table #table [dataSource]="dataSourceNew">


       <ng-container  *ngFor="let head of tableData.record; let i= index; " matColumnDef="{{head}}" (click)="setClickedRow(ddata) "  [class.active]="ddata[primaryid] == selectedRow">
               <mat-header-cell *matHeaderCellDef> {{tableData.gridhead[i]}} 
                </mat-header-cell>
              <mat-cell *matCellDef="let element"> {{element[head]}} </mat-cell>
         </ng-container>


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

Now I want to attach a pagination to this table and for that I have declared this

 @ViewChild(MatPaginator) paginator: MatPaginator;

But When I attach the pagination to table in html like this,

  <mat-paginator #paginator
                 [pageSize]="10"
                 [pageSizeOptions]="[5, 10, 20]"
                 [showFirstLastButtons]="true">
  </mat-paginator>

I got the below error in console and it breaks my application.

I have already imported this

import {MatPaginator, MatTableDataSource} from '@angular/material';

In respective .ts file.

Uncaught Error: Template parse errors:
Can't bind to 'pageSize' since it isn't a known property of 'mat-paginator'.
1. If 'mat-paginator' is an Angular component and it has 'pageSize' input, then verify that it is part of this module.
2. If 'mat-paginator' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.

Also when I log this.dataSourcenew: The paginator element of this object is empty : How can I use the angular material paginator without creating any interface?

Update :

With David's suggestion : I have added MatPaginator to the main app module's imports. Now the pagination block is showing perfectly.

But the Current Records shows as "0 of 0". even though I have 14 records, and Pagination functions like changing number of records,next, previous etc are not working. What I am missing?

Update 2: I have applied the property Length to paginator tags.Now The pagination is working fine. The issue is that now the datatable is not changing the current no. of rows.

Update 3: As per the suggestion from Pierre Mallet I have done the needed changes. and now without explicitly telling the [length] total record is getting inferred from the api response. Also the paginator is correctly binded with my this.matdatasource = new MatTableDataSource([]); So no explicit codding is done till now to achieve this.

Now I just want to fetch few records initially (lets say 20) and then want to do database call from subsequent requests, so that I don't need to hit the db at once for all the records. How to achieve this?

like image 317
Talk is Cheap Show me Code Avatar asked Mar 05 '18 10:03

Talk is Cheap Show me Code


2 Answers

First, instantiate the paginator

@ViewChild(MatPaginator) paginator: MatPaginator;

Then populate the dataSource

this.matdatasource = new MatTableDataSource([])

And finally

this.dataSource.paginator = this.paginator;

Check this for proper Understanding

like image 185
Akitha_MJ Avatar answered Sep 22 '22 12:09

Akitha_MJ


You could try @matheo/datasource to build a clean setup of your database and datasource, and get everything in place without headaches.

I've mount different APIs with all kinds of pagination responses (and also no pagination data like Firebase), and I've handled the total count for all those cases with no issues.

Further details can be found at:
https://medium.com/@matheo/reactive-datasource-for-angular-1d869b0155f6

I could help you with your use case if you like the library
Happy coding!

like image 34
Mateo Tibaquira Avatar answered Sep 19 '22 12:09

Mateo Tibaquira