0
votes

I'm working on an Angular 5 project and I have a table with data that I'm displaying. The table is a MatTableModule from angular material. This is a two part question.

I have a service that fires a GET request to my API and returns all the data, which I'm handling in my component.ts file below. All this works fine but the table is not responsive on smaller screens hence I need to be able to loop through the returned data and display it in another, non-tabular format on smaller screens. However, I can't figure out how to.

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { DataSource } from '@angular/cdk/collections';
import { RoutesService } from '../../services/routes/routes.service';
import { Routes } from '../../services/models/routes.model';

@Component({...})
export class RoutesComponent implements OnInit {

  public displayedColumns = ['from', 'to', 'departures', 'duration', 'price'];
  public dataSource = new RoutesDataSource(this.routesService);

  constructor(private routesService: RoutesService) { }

  ngOnInit() { }
}

export class RoutesDataSource extends DataSource<any> {
  public iterable: string[] = ["foo", "bar"];
  
  constructor(private routes: RoutesService) {
    super();
  }

  connect(): Observable<Routes[]> {
    return this.routes.getRoutes();
  }

  disconnect() {}
}

My template file

<mat-table [dataSource]="dataSource">
  <!-- From Column -->
  <ng-container matColumnDef="from">
    <mat-header-cell *matHeaderCellDef> From </mat-header-cell>
    <mat-cell *matCellDef="let route"> {{route.from}} </mat-cell>
  </ng-container>

  <!-- To Column -->
  <ng-container matColumnDef="to">
    <mat-header-cell *matHeaderCellDef> To </mat-header-cell>
    <mat-cell *matCellDef="let route"> {{route.to}} </mat-cell>
  </ng-container>

  <!-- Departures Column -->
  <ng-container matColumnDef="departures">
    <mat-header-cell *matHeaderCellDef> Departures </mat-header-cell>
    <mat-cell *matCellDef="let route">{{route.departures}}</mat-cell>
  </ng-container>

  <!-- Duration Column -->
  <ng-container matColumnDef="duration">
    <mat-header-cell *matHeaderCellDef> Duration </mat-header-cell>
    <mat-cell *matCellDef="let route"> {{route.duration}} </mat-cell>
  </ng-container>

  <!-- Price Column -->
  <ng-container  matColumnDef="price">
    <mat-header-cell *matHeaderCellDef> Avg_price </mat-header-cell>
    <mat-cell *matCellDef="let route">
        <button mat-raised-button color="primary">{{route.avg_price}}</button>
    </mat-cell>
  </ng-container>

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

What I'd like to do is be able to loop over the returned data from outside mat-table. Apparently binding dataSource to the mat-table somehow automatically subscribes to the service and I'm able to access the values in there. I just need to be able to do the same outside mat-table.

And while at it, I also would like to know how I can access that iterable property in the RoutesDataSource class from inside the Component class. How do I do that? And I can't figure out how to add syntax highlighting on this code!

Any help would be greatly appreciated. Thanks.

1

1 Answers

0
votes

Found a work around to this problem. I added a class property items like so...

public items: Array<any> = []

then in the ngOnInit() method...

  ngOnInit() {
    this.routesService.getRoutes().subscribe((data) => {
      if (data) {
        this.items = data;
      }
    });
  }

Hence, I was able to access and loop over the 'items' in my template and get my desired outcome. The only issue with this is that you end up subscribing to the same service twice in one component but otherwise, it works just fine.