Search code examples
angularasp.net-coremat-table

mat-table rendering but no data shows - Angular


Update: I have been messing with this for quiet awhile now and can now see the column names but data is still only showing in the API call.

I am trying to display this data in a table, everything ive seen so far that has had this issue is because the displayColumns value wasnt correct. That isnt my problem here, I dont think, so im wondering what else I am missing here.

Something to note is the data is reaching my front end from my database and i can see it in my network tab, so i know the data is making "available"

Here is my markup:

<p>view-workouts works!</p>
 
<div class="mat-elevation-z8"> 
<table mat-table [dataSource]="dataSource" matSort >

    <ng-container matColumnDef="exerciseId">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>Exercise Number</th>
        <td mat-cell *matCellDef="let entry">{{ entry.exerciseId }}</td>
    </ng-container>

    <ng-container matColumnDef="exerciseName">
        <th mat-header-cell *matHeaderCellDef>Exercise Name</th>
        <td mat-cell *matCellDef="let entry">{{ entry.ExerciseName }}</td>
    </ng-container>

    <ng-container matColumnDef="muscleGroupId">
        <th mat-header-cell *matHeaderCellDef>Muscle Group</th>
        <td mat-cell *matCellDef="let entry">{{ entry.MuscleGroupId }}</td>
    </ng-container>
    
    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator class="mat-elevation-z8"
                    [pageSize]="3"
                    [pageSizeOptions]="[3,5,10]"
                    [showFirstLastButtons]="true">
</mat-paginator>
</div>

This is my ts:

import { Component, OnInit, ViewChild } from '@angular/core';
import { IExercises } from 'src/app/models/IExcercises';
import { WorkoutService } from '../../services/workout.services'
import { MatPaginator} from '@angular/material/paginator';
import { Subscription } from 'rxjs';
import { MatSort, MatTableDataSource } from '@angular/material';
import { HttpErrorResponse } from '@angular/common/http';

@Component({
  selector: 'app-view-exercise',
  templateUrl: './view-exercise.component.html',
  styleUrls: ['./view-exercise.component.css']
})
export class ViewExerciseComponent implements OnInit {
  errorMessage: string;
  isLoadingData = true;

  private subs = new Subscription
  private dataArray: any;

  dataSource: MatTableDataSource<IExercises>;
  displayedColumns = ['exerciseId','exerciseName','muscleGroupId'];
  @ViewChild(MatPaginator, { static: true}) paginator: MatPaginator;
  @ViewChild(MatSort, {static: true}) sort: MatSort;

  constructor(private workoutService: WorkoutService) { }

  ngOnInit() { 
    this.subs.add(this.workoutService.getExercises()
    .subscribe((res) =>
      {
        this.dataSource = new MatTableDataSource<IExercises>(this.dataArray);
        this.dataSource.paginator = this.paginator;
        this.dataSource.sort = this.sort;
      },
      (error: HttpErrorResponse) => {
        console.log(error);
      }));
   }

   ngOnDestroy() {
     if (this.subs) {
       this.subs.unsubscribe();
     }
   }
}

Solution

  • There is a few issues with the code as ill lay out below. Ill also show the correct code that worked for me.

    1. Didnt import MatMenuModule to app.module.ts after fixing that there was a few other issues that where created
    2. The ts Model or interface and c# model names didnt match
    3. the subscribe and service call was jacked up.

    HTML

    <div class="mat-elevation-z8"> 
    <table mat-table [dataSource]="dataSource">
    
        <ng-container matColumnDef="exerciseId">
            <th mat-header-cell *matHeaderCellDef>Exercise Number</th>
            <td mat-cell *matCellDef="let entry">{{ entry.exerciseId }}</td>
        </ng-container>
    
        <ng-container matColumnDef="exerciseName">
            <th mat-header-cell *matHeaderCellDef>Exercise Name</th>
            <td mat-cell *matCellDef="let entry">{{ entry.exerciseName }}</td>
        </ng-container>
    
        <ng-container matColumnDef="muscleGroupId">
            <th mat-header-cell *matHeaderCellDef>Muscle Group</th>
            <td mat-cell *matCellDef="let entry">{{ entry.muscleGroupId }}</td>
        </ng-container>
        
        <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
        <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
    </table>
    </div> 
    

    ts

    import { Component, OnInit, ViewChild } from '@angular/core';
    import { IExercises } from 'src/app/models/IExcercises';
    import { WorkoutService } from '../../services/workout.services'
    import { finalize } from 'rxjs/operators';
    import { MatPaginator} from '@angular/material/paginator';
    import { MatSort, MatTableDataSource } from '@angular/material';
    
    @Component({
      selector: 'app-view-exercise',
      templateUrl: './view-exercise.component.html',
      styleUrls: ['./view-exercise.component.css']
    })
    export class ViewExerciseComponent implements OnInit {
      errorMessage: string;
      isLoadingData = true;
    
      dataSource: MatTableDataSource<IExercises>;
      displayedColumns = ['exerciseId','exerciseName','muscleGroupId'];
      //@ViewChild(MatPaginator, { static: true}) paginator: MatPaginator;
      //@ViewChild(MatSort, {static: true}) sort: MatSort;
    
      constructor(private workoutService: WorkoutService) { }
    
      ngOnInit() {
        this.refreshExercises();
      }
    
      refreshExercises() {
         this.workoutService.getExercises().pipe(
          finalize(() => this.isLoadingData = false)
        )
          .subscribe((exercises: IExercises[]) => {
            this.dataSource = new MatTableDataSource<IExercises>(exercises)
            //this.dataSource.paginator = this.paginator
          },
            (error: Error) => this.errorMessage = error.message);
        }
    }