3
votes

I currently have a table that is being populated with data coming from Firestore. I'm having trouble implementing sorting, pagination, and filtering to this and I was hoping someone could shed some light on this for me. Below is my service, component, and html. I've seen the different examples on material.angular.io but the example database they use throws me off.

service:

import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';
import { Account } from './../models/account.model';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class AccountService {
  accountsCollection: AngularFirestoreCollection<Account>;
  accounts: Observable<Account[]>;

  constructor(public afs: AngularFirestore) {
    this.accountsCollection = afs.collection('accounts');

    this.accounts = this.accountsCollection.snapshotChanges().map(changes => {
      return changes.map(a => {
        const data = a.payload.doc.data() as Account;
        data.id = a.payload.doc.id;
        return data;
      });
    });
  }

  getAccounts() {
    return this.accounts;
  }

 }

component:

import { Account } from './../../../models/account.model';
import { Component, ViewChild, OnInit } from '@angular/core';
import { DataSource } from '@angular/cdk/collections';
import { MatPaginator, MatSort } from '@angular/material';
import { Observable } from 'rxjs/Observable';
import { AccountService } from '../../../services/account.service';

@Component({
  selector: 'app-account-table',
  templateUrl: './account-table.component.html',
  styleUrls: ['./account-table.component.css']
})
export class AccountTableComponent implements OnInit {
  dataSource = new AccountDataSource(this.accountService);
  displayedColumns = [
    'salesStep',
    'status',
    'idn',
    'hospital',
    'state',
    'regionalManager',
    'accountExecutive',
    'clientLiaison',
    'gpo'
  ];

  constructor(private accountService: AccountService) {}

  ngOnInit() {

  }

}

export class AccountDataSource extends DataSource<any> {

  constructor(private accountService: AccountService) {
    super();
  }

  connect(): Observable<Account[]> {
    return this.accountService.getAccounts();
  }

  disconnect() {}

}

html:

<div class="example-header">
  <mat-form-field>
    <input matInput #filter placeholder="Search">
  </mat-form-field>
</div>

<mat-card class="example-container">

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

    <!--- Note that these columns can be defined in any order.
          The actual rendered columns are set as a property on the row definition" -->

    <!-- Sales Step Column -->
    <ng-container matColumnDef="salesStep">
      <mat-header-cell *matHeaderCellDef mat-sort-header> Sales Step </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.salesStep}} </mat-cell>
    </ng-container>

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

    <!-- IDN Column -->
    <ng-container matColumnDef="idn">
      <mat-header-cell *matHeaderCellDef mat-sort-header> IDN </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.idn}} </mat-cell>
    </ng-container>

    <!-- Hospital Column -->
    <ng-container matColumnDef="hospital">
      <mat-header-cell *matHeaderCellDef mat-sort-header> Hospital </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.hospital}} </mat-cell>
    </ng-container>

    <!-- State Column -->
    <ng-container matColumnDef="state">
      <mat-header-cell *matHeaderCellDef mat-sort-header> State </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.state}} </mat-cell>
    </ng-container>

    <!-- Regional Manager Column -->
    <ng-container matColumnDef="regionalManager">
      <mat-header-cell *matHeaderCellDef mat-sort-header> RM </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.regionalManager}} </mat-cell>
    </ng-container>

    <!-- Account Executive Column -->
    <ng-container matColumnDef="accountExecutive">
      <mat-header-cell *matHeaderCellDef mat-sort-header> AE </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.accountExecutive}} </mat-cell>
    </ng-container>

    <!-- Client Liaison Column -->
    <ng-container matColumnDef="clientLiaison">
      <mat-header-cell *matHeaderCellDef mat-sort-header> CL </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.clientLiaison}} </mat-cell>
    </ng-container>

    <!-- GPO Column -->
    <ng-container matColumnDef="gpo">
      <mat-header-cell *matHeaderCellDef mat-sort-header> GPO </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.gpo}} </mat-cell>
    </ng-container>



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

  <!-- <div class="example-no-results"
       [style.display]="dataSource.renderedData.length == 0 ? '' : 'none'">
    No accounts found matching filter.
  </div> -->

  <mat-paginator #paginator
                [length]="(accountService.accounts | async)?.length"
                [pageIndex]="0"
                [pageSize]="25"
                [pageSizeOptions]="[5, 10, 25, 100]">
  </mat-paginator>
</mat-card>
1
You may want to change DataSource to MatTableDataSource which is new. material2-docs-dev.firebaseapp.com/components/table/…. Be sure to upgrade to Angular 5 and Material RC. I would refer you to my answers on S.O. for Firebase but they are mostly obsolete now. I'm also struggling with the new setup and working on it today. When I find a solution it won't help you because you have the old table setup which seems to be deprecated.Preston
I'm currently using Angular 5 and with "@angular/material": "^2.0.0-beta.12", but it looks like I need to use the the snapshot build (npm install --save angular/material2-builds angular/cdk-builds) to have access to MatTableDataSource correct?Kyle
I just finished installing the snapshot build and implemented everything with MatTableDataSource and it works like a charm! Thank you very much!Kyle
Yep, the new Mat Table is faster and easier to setup, fortunately.Preston

1 Answers

1
votes

I was able to implement pagination, sorting, and filtering by installing the snapshot build (npm install --save angular/material2-builds angular/cdk-builds) and using MatTableDataSource. For examples on how to use this: https://material2-docs-dev.firebaseapp.com/components/table/examples