0
votes

So I am having issues with implementing MatSort and MatPaginator. I followed the tutorials on the offical angular material website (https://material.angular.io/components/sort/overview). However, every time I try to implement it, it doesn't work. I get 0 errors in my console log so I have no clue what I am missing.

messages.component.ts:

import { Component, OnInit, ViewChild, } from '@angular/core';
import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material';
import { MessagesService } from '../shared/services/messages.service';
import { IMessageCredentials } from '../shared/interfaces/messageCredentials.interface';
import { IMessage, IMessageData } from '../shared/interfaces/messages.interface';
import { IDriverData } from '../shared/interfaces/driver.interface';
import { DriverService } from '../shared/services/driver.service';

@Component({
  selector: 'app-messages',
  templateUrl: './messages.component.html',
  styleUrls: ['./messages.component.scss']
})

export class MessagesComponent implements OnInit {  
  name: string = '';
  number: string = '';
  content: string = '';
  dataSource: MatTableDataSource<IMessageData>
  messagesData: IMessageData[];
  driverData: IDriverData[];

  displayedColumns: string[] = ['number', 'chauffeur' , 'executionDateTime', 'textDecoded', 'richting'];

  @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
  @ViewChild(MatSort, { static: true }) sort: MatSort;

  constructor(private messageService: MessagesService, private driverService: DriverService) { 
    this.getDrivers();
    this.dataSource = new MatTableDataSource(this.messagesData);
  }

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

  getMessages() {
    let credentials = <IMessageCredentials>{};
    credentials.login = "";
    credentials.password = "";
    credentials.unreadOnly = false;

    this.messageService.getAll(credentials).subscribe(response => {
      this.messagesData = response;
      this.dataSource = new MatTableDataSource(this.messagesData);
    })    
  }

  sendMessages() {
    let message = <IMessage>{};
    message.login = "";
    message.password = "";
    message.number = this.number;
    message.content = this.content;

    this.messageService.sendMessage(message).subscribe(response => {
      console.log("Send message: " + response)
    })

    window.alert("Send message to: " + this.number);
    this.content = "";
  }

  getDrivers() {
    let isAutoComplete: boolean = true;

    this.driverService.getDrivers(isAutoComplete).subscribe(response => {
      this.driverData = response;
    })
  }

  checkForDriverNames(phoneNumber: string) : string {
    let result = "";

    this.driverData.forEach(element => {      
      if (element.phone === phoneNumber){
        result = element.name;
      }
    });

    return result;
  }

  checkTraffic(folderNumber: string) : string {
    let result = parseInt(folderNumber) === 1 ? 'Ontvangen' : 'Verstuurd';

    return result;
  }
}

messages.component.html:

<div class="messages">
    <button mat-raised-button (click)="getMessages()">Refresh</button>

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

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

        <ng-container matColumnDef="chauffeur">
            <th mat-header-cell *matHeaderCellDef mat-sort-header>Chauffeur</th>
            <td mat-cell *matCellDef="let row">{{checkForDriverNames(row.number)}}</td>
        </ng-container>

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

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

        <ng-container matColumnDef="richting">
            <th mat-header-cell *matHeaderCellDef mat-sort-header>Richting</th>
            <td mat-cell *matCellDef="let row">{{checkTraffic(row.folder)}}</td>
        </ng-container>

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

    <mat-paginator [pageSizeOptions]="[5, 10, 15]" showFirstLastButtons></mat-paginator>
</div>

messages.module.ts:

import { NgModule } from '@angular/core';
import { MessagesComponent } from './messages.component';
import { BrowserModule } from '@angular/platform-browser';

import { SharedModule } from '../shared/shared.module';

import {
  MatSelectModule,
  MatCardModule,
  MatTableModule,
  MatCheckboxModule,
  MatPaginatorModule,
  MatSortModule
} from '@angular/material';

@NgModule({
  declarations: [
    MessagesComponent
  ],
  imports: [
    BrowserModule,
    SharedModule,
    MatCardModule,
    MatSelectModule,
    MatTableModule,
    MatCheckboxModule,
    MatPaginatorModule,
    MatSortModule
  ],
  exports: [
    MessagesComponent    
  ],
  providers: [],
  bootstrap: []
})
export class MessagesModule { }
3
Can you provide stackblitz demo?Prashant Pimpale

3 Answers

3
votes

This line:

this.dataSource = new MatTableDataSource(this.messagesData); 

It overrides the paginator & sort (Resets to null), so try like below:

this.messageService.getAll(credentials).subscribe(response => {
   this.messagesData = response;
   this.dataSource = new MatTableDataSource(this.messagesData);
   this.dataSource.paginator = this.paginator;
   this.dataSource.sort = this.sort;
});
3
votes

As per my knowelage this is a matter of async and sync methods. Try this:

ngOnInit(): void {
    this.messageService.getAll(credentials).subscribe(response => {
      this.messagesData = response;
      this.dataSource = new MatTableDataSource(this.messagesData);    
      this.dataSource.paginator = this.paginator;
      this.dataSource.sort = this.sort;
   }) 
}
0
votes

Remove this line from your constructor because messagesData is not populated yet.

this.dataSource = new MatTableDataSource(this.messagesData);

Plus add this line to your ngInit

// If the user changes the sort order, reset back to the first page.
this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);

I never work with Angular material 8.x, however if it's not working, you could try to change this line (it's the way i'm doing it with Angular material 7.x)

this.dataSource = new MatTableDataSource(this.messagesData);

to

this.dataSource.data = new MatTableDataSource(this.messagesData);

Full code (no tested)

import { Component, OnInit, ViewChild, } from '@angular/core';
import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material';
import { MessagesService } from '../shared/services/messages.service';
import { IMessageCredentials } from '../shared/interfaces/messageCredentials.interface';
import { IMessage, IMessageData } from '../shared/interfaces/messages.interface';
import { IDriverData } from '../shared/interfaces/driver.interface';
import { DriverService } from '../shared/services/driver.service';

@Component({
  selector: 'app-messages',
  templateUrl: './messages.component.html',
  styleUrls: ['./messages.component.scss']
})

export class MessagesComponent implements OnInit {  
  name: string = '';
  number: string = '';
  content: string = '';
  dataSource: MatTableDataSource<IMessageData>
  messagesData: IMessageData[];
  driverData: IDriverData[];

  displayedColumns: string[] = ['number', 'chauffeur' , 'executionDateTime', 'textDecoded', 'richting'];

  @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
  @ViewChild(MatSort, { static: true }) sort: MatSort;

  constructor(private messageService: MessagesService, private driverService: DriverService) { 
    this.getDrivers();
  }

  ngOnInit(): void {
    // If the user changes the sort order, reset back to the first page.
    this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);
    this.getMessages();
   }

  getMessages() {
    let credentials = <IMessageCredentials>{};
    credentials.login = "";
    credentials.password = "";
    credentials.unreadOnly = false;

    this.messageService.getAll(credentials).subscribe(response => {
      this.messagesData = response;
      this.dataSource = new MatTableDataSource(this.messagesData);
    })    
  }

  sendMessages() {
    let message = <IMessage>{};
    message.login = "";
    message.password = "";
    message.number = this.number;
    message.content = this.content;

    this.messageService.sendMessage(message).subscribe(response => {
      console.log("Send message: " + response)
    })

    window.alert("Send message to: " + this.number);
    this.content = "";
  }

  getDrivers() {
    let isAutoComplete: boolean = true;

    this.driverService.getDrivers(isAutoComplete).subscribe(response => {
      this.driverData = response;
    })
  }