4

I have the following angular material table with data source property:

<div class="dim">
  <mat-form-field >
    <input matInput class="warn" (keyup)="applyFilter($event.target.value)" placeholder="Search">
    <mat-icon matSuffix>search</mat-icon>
  </mat-form-field>
</div>
<div class="mat-elevation-z2">
  <table mat-table [dataSource]="dataSource" matSort>
    <ng-container matColumnDef="unit_id">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>ID</th>
      <td class="alignTd" mat-header *matCellDef="let row">{{row.id}}</td>
    </ng-container>

    <ng-container matColumnDef="unit_type">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Type</th>
      <td mat-header *matCellDef="let row">{{row.unit_type}}</td>
    </ng-container>

    <ng-container matColumnDef="location_id_auto">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Location</th>
      <td mat-header *matCellDef="let row">{{row.location}}</td>
    </ng-container>

    <ng-container matColumnDef="user_id">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>User</th>
      <td mat-header *matCellDef="let row">{{row.user}}</td>
    </ng-container>

    <ng-container matColumnDef="unit_number_hh">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Number Of units</th>
      <td mat-header *matCellDef="let row">{{row.unit_number}}</td>
    </ng-container>

    <ng-container matColumnDef="unit_status">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Status</th>
      <td mat-header *matCellDef="let row">{{row.status}}</td>
    </ng-container>

    <ng-container matColumnDef="unit_date_added">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Date Added</th>
      <td mat-header *matCellDef="let row">{{row.date_added}}</td>
    </ng-container>
    <tr class="example-expanded-row" mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns;">

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

And here is the corresponding typescript for it:

import { Component, OnInit, ViewChild } from '@angular/core';
import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material';
import { HttpClient } from 'selenium-webdriver/http';
import { AuthApiService } from '../../auth-api.service';

@Component({
  selector: 'app-registration',
  templateUrl: './registration.component.html',
  styleUrls: ['./registration.component.css']
})
export class RegistrationComponent implements OnInit {
  dataSource:  any;
  displayedColumns: String[]=['unit_id', 'unit_type', 'location_id_auto', 'user_id', 'unit_number_hh', 'unit_status', 'unit_date_added'];
  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;
  constructor(private auth: AuthApiService) { }

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

  applyFilter(filterValue: string){
    this.dataSource.filter = filterValue.trim().toLowerCase();

    if(this.dataSource.paginator)
    {
      this.dataSource.paginator.firstPage();
    }
  }

  getUnitData(){
    this.auth.getUnitDataService().subscribe(
      (data)=>
      {
        this.dataSource = Object.values(data);
      },
      (error)=>
      {
        console.log("Error: "+error)
      }
    )

  }

}

I am getting the data and are displayed normally, but I have 6 records, and instead of displaying 5 on the first page and 1 on the other, all 6 rows are displayed on the first page, and the filter is not working at all.

Here is a plunker, you can add an array of data instead.

I have the following error:

ERROR TypeError: Cannot read property 'paginator' of undefined at RegistrationComponent.push../src/app/dashboard/registration/registration.component.ts.RegistrationComponent.ngOnInit (registration.component.ts:20)

enter image description here

alim1990
  • 4,656
  • 12
  • 67
  • 130

3 Answers3

9

Your function getUnitData() is asynchronous and not done in the moment when you access this.dataSource. Change the function to this

getUnitData() {
    this.auth.getUnitDataService().subscribe(
      (data) => {
        this.dataSource = new MatTableDataSource(data);
        this.dataSource.paginator = this.paginator;
        this.dataSource.sort = this.sort;
      },
      (error) => {
        console.log("Error: "+error)
      });
}

also adjust your html

<mat-paginator #paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
alsami
  • 8,996
  • 3
  • 25
  • 36
1

dataSource type must be MatTableDataSource

You have declared like this,

dataSource = new MatTableDataSource();
Aniket Avhad
  • 4,025
  • 2
  • 23
  • 29
  • The filter is working now, but the pagination is still wrong. – alim1990 Sep 03 '18 at 08:52
  • That is not the problem at all. The samples on material website also don't define it that way. – alsami Sep 03 '18 at 08:56
  • @aslami- share the link with me..where they not declare dataSource as MatTableDataSource – Aniket Avhad Sep 03 '18 at 08:58
  • @aslami- also create example where only declare datasource as any and access paginator on ngOnInit() and then tell me is paginator accessible from datasource or not. – Aniket Avhad Sep 03 '18 at 09:01
  • @AniketAvhad here: https://material.angular.io/components/table/examples – alsami Sep 03 '18 at 09:03
  • alsami as @droidnation using type as any then the error because of that only..i tried in my project as well.. – Aniket Avhad Sep 03 '18 at 09:06
  • Just check out the sample code. The problem is not the matdatasource, we are using typescript it can be anything like in the samples. The problem was data is loaded asynchronous and datasource is being accessed before being initialized. – alsami Sep 03 '18 at 09:07
1

In html bind paginator

<mat-paginator #paginator [pageSize]="5" [pageSizeOptions]="[5, 10, 25, 50]">
        </mat-paginator>

In ts file

  dataSource = new MatTableDataSource<any>();

and need to add in

   ngAfterViewInit() {
     this.dataSource.paginator = this.paginator;
     this.dataSource.sort = this.sort;
   }
Nenad Radak
  • 3,550
  • 2
  • 27
  • 36