How can I populate a mat-table in Angular 7 with data stored in an object?

At the moment, my code is set up to populate a table with data.

In my component.ts file:

import { HttpClient } from "@angular/common/http";
import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { ActivatedRoute, Router } from "@angular/router";
import { MatTableDataSource } from "@angular/material/table";

@Component({
  styleUrls: ["./styles.scss"],
  templateUrl: "./template.html"
})
export class DisplayEmployeeData {
  employeeDataSheet: object;

  constructor(private http: HttpClient) {}

  ngOnInit() {
    this.http
      .get("http://localhost:5000/EmployeeData/GetData")
      .subscribe(response => {
        this.employeeDataSheet = response;
      });
  }
}

The template.html code structure is as follows:

<mat-card style="height: 98%">
  <div style="height: 95%; overflow: auto;">
      <table class="StyledTable">
        <thead>
          <tr>
            <td>Name</td>
            <td>Age</td>
            <td>Date Of Birth</td>
            <td>Address</td>
            <td>Postcode</td>
            <td>Gender</td>
            <td>Salary</td>
            <td>Job Title</td>
          </tr>
        </thead>

        <tr *ngFor="let info of employeeDataSheet">
          <td>{{info.Name}}</td>
          <td>{{info.Age}}</td>
          <td>{{info.DateOfBirth}}</td>
          <td>{{info.Address}}</td>
          <td>{{info.Postcode}}</td>
          <td>{{info.Gender}}</td>
          <td>{{info.Salary}}</td>
          <td>{{info.JobTitle}}</td>
      </table>
    </div>

</mat-card>

Although functional, I find the appearance unattractive. My goal is to implement a mat-table according to https://material.angular.io/components/table/examples

I have made changes in the template.html as follows:

<mat-card style="height: 98%">
    <table mat-table [dataSource]="employeeDataSheet" class="mat-elevation-z8">
        <ng-container matColumnDef="Name">
            <th mat-header-cell *matHeaderCellDef>Name </th>
            <td mat-cell *matCellDef="let element"> {{element.Name}} </td>
        </ng-container>
        <ng-container matColumnDef="DateOfBirth">
            <th mat-header-cell *matHeaderCellDef> DateOfBirth </th>
            <td mat-cell *matCellDef="let element"> {{element.DateOfBirth}} </td>
        </ng-container>
        <ng-container matColumnDef="Address">
            <th mat-header-cell *matHeaderCellDef> Address </th>
            <td mat-cell *matCellDef="let element"> {{element.Address}} </td>
        </ng-container>
        <ng-container matColumnDef="Postcode">
            <th mat-header-cell *matHeaderCellDef> Postcode </th>
            <td mat-cell *matCellDef="let element"> {{element.Postcode}} </td>

        <ng-container matColumnDef="Gender">
            <th mat-header-cell *matHeaderCellDef> Gender </th>
            <td mat-cell *matCellDef="let element"> {{element.Gender}} </td>
        </ng-container>
        <ng-container matColumnDef="Salary">
            <th mat-header-cell *matHeaderCellDef> Salary </th>
            <td mat-cell *matCellDef="let element"> {{element.Salary}} </td>
        </ng-container>
        <ng-container matColumnDef="JobTitle">
            <th mat-header-cell *matHeaderCellDef> JobTitle </th>
            <td mat-cell *matCellDef="let element"> {{element.JobTitle}} </td>
        </ng-container>

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

However, upon running this updated code, the screen remains blank without any error messages. What amendments should be made in the template.html and/or component.ts to display the data correctly?

Answer №1

Make the following modifications:

In component.ts:

import { HttpClient } from "@angular/common/http";
import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { ActivatedRoute, Router } from "@angular/router";
import { MatTableDataSource } from "@angular/material";
import { MyObject} from "../my-object.model";

@Component({
   styleUrls: ["./styles.scss"],
   templateUrl: "./template.html"
})
export class MyRouteData implements OnInit {
   employeeInfoTable : MyObject[] = [];
   employeeInfoTableDataSource = new MatTableDataSource(this.employeeInfoTable);
   displayedColumns: string[] = [
     "Name",
     "DateOfBirth",
     "Address",
     "Postcode",
     "Gender",
     "Salary"
     "JobTitle"
  ];

   constructor(private http: HttpClient) {}

   ngOnInit() {
      this.http.get("http://localhost:5000/MyRoute/GetEmployeeInfo")
          .subscribe(response => {
             this.employeeInfoTable = response;
             this.employeeInfoTableDataSource.data = this.employeeInfoTable;
      });
   }
}

In my-object.model.ts

export interface MyObject{
   id: number;
   Name: string;
   DateOfBirth: Date;
   Address: string;
   Postcode: string;
   Gender: string;
   Salary : number;
   JobTitle : string;
}

In your .html

<mat-card style="height: 98%">
  <table mat-table [dataSource]="employeeInfoTableDataSource" class="mat-elevation-z8">
    <ng-container matColumnDef="Name">
        <th mat-header-cell *matHeaderCellDef>Name </th>
        <td mat-cell *matCellDef="let element"> {{element.Name}} </td>
    </ng-container>
    <ng-container matColumnDef="DateOfBirth">
        <th mat-header-cell *matHeaderCellDef> DateOfBirth </th>
        <td mat-cell *matCellDef="let element"> {{element.DateOfBirth}} </td>
    </ng-container>
    <ng-container matColumnDef="Address">
        <th mat-header-cell *matHeaderCellDef> Address </th>
        <td mat-cell *matCellDef="let element"> {{element.Address}} </td>
    </ng-container>
    <ng-container matColumnDef="Postcode">
        <th mat-header-cell *matHeaderCellDef> Postcode </th>
        <td mat-cell *matCellDef="let element"> {{element.Postcode}} </td>

    <ng-container matColumnDef="Gender">
        <th mat-header-cell *matHeaderCellDef> Gender </th>
        <td mat-cell *matCellDef="let element"> {{element.Gender}} </td>
    </ng-container>
    <ng-container matColumnDef="Salary">
        <th mat-header-cell *matHeaderCellDef> Salary </th>
        <td mat-cell *matCellDef="let element"> {{element.Salary}} </td>
    </ng-container>
    <ng-container matColumnDef="JobTitle">
        <th mat-header-cell *matHeaderCellDef> JobTitle </th>
        <td mat-cell *matCellDef="let element"> {{element.JobTitle}} </td>
    </ng-container>

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

Answer №2

To enhance the functionality of your Component.ts file, you should implement 2 key modifications:

1) Define the 'displayedColumns' property. (It's worth noting that having 2 'Postcode' columns in your table is not permitted. I have removed one instance from the displayedColumns definition and recommend removing it from your HTML table as well).

public displayedColumns = ['Name', 'DateOfBirth', 'address', 'Postcode', 'Gender', 'Salary', 'JobTitle', 'inbound', 'ping_time'];

2) Set the response data to employeeInfoTable as a MatTableDataSource type. This assignment will be essential for handling individual rows effectively.

public employeeInfoTable: any;
this.employeeInfoTable = new MatTableDataSource<any>([...response]);;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Potential Issue: TypeScript appears to have a bug involving the typing of overridden methods called by inherited methods

I recently came across a puzzling situation: class A { public method1(x: string | string[]): string | string[] { return this.method2(x); } protected method2(x: string | string[]): string | string[] { return x; } } class B extends A { prot ...

Struggling with the TypeScript generic syntax for the GroupBy function

Struggling to figure out where I'm going wrong with this TypeScript signature after spending some time on it. I've been working on a group by function: const group = <T>(items: T[], fn: (item: T) => T[keyof T]) => { return items.re ...

In Angular 2+, what is the best method for displaying elements based on whether the user is logged in or logged out?

Struggling with the transition from AngularJS to Angular 2+ for my app. I'm facing challenges implementing a simple feature that was previously effortless in AngularJS. The issue is with the top navigation - I want it to display a LOG IN button when ...

Tips for handling various HTTP requests until a response is received

For my application, I have a need to make multiple http calls before proceeding to create certain objects. Only after all the http requests have received responses from the servers can I process the results and construct my page. To handle this scenario, ...

Navigating a relative path import to the correct `@types` in Typescript

When the browser runs, I require import * as d3 from '../lib/d3.js'; for d3 to be fetched correctly. I have confirmed that this does work as intended. However, the file that contains the above code, let's call it main.js, is generated from ...

Unable to navigate using react-router after logging out without a page refresh

In my logout approach, everything seems to work fine - there are no errors in the console, localHistory is cleared successfully, but for some reason it cannot navigate to the login page without refreshing the current page. const handleLogout = () => { ...

The issue persists in VSCode where the closing brackets are not being automatically added despite

Recently, I've noticed that my vscode editor is failing to automatically add closing brackets/parenthesis as it should. This issue only started happening recently. I'm curious if anyone else out there has encountered this problem with their globa ...

What is the purpose of the tabindex in the MUI Modal component?

Struggling with integrating a modal into my project - it's refusing to close and taking up the entire screen height. On inspection, I found this troublesome code: [tabindex]: outline: none; height: 100% How can I remove height: 100% from the ...

Having trouble reaching the angular app when using nginx and istio

I am currently working on setting up an Istio service mesh for a project that involves .NET Core services and Angular 6 as the front end. Interestingly, when I deploy the application with built-in Docker applications, everything runs smoothly. For exampl ...

Passing input values from a parent component to a child component in Angular is not functioning as expected

I am facing an issue with implementing a basic @Input in Angular. Despite setting the value in the parent component template as follows: <app-summary-data-row> [test] = "'ttt'" </app-summary-data-row> In the child component, I h ...

What effect does choosing an image in my user interface have on halting my Web API?

When launching my .NET Core 3 Web API in Visual Studio 2019, everything runs smoothly and handles requests without issue. However, an unexpected problem arises when I interact with my Angular UI. Upon navigating to a new section designed for selecting fil ...

The sequence of activities within the Primeng Multiselect component

Lately, I've encountered an issue while using the multiselect component from the primeng library in Angular. Everything was going smoothly until I noticed a strange problem with the order of events. Here is an example that showcases the issue: https:/ ...

TypeScript in Angular causing lodash tree shaking failure

I am currently working on a large project that involves TypeScript. Various attempts have been made to optimize the use of lodash in my project. Before making any conclusions, I believe it is important to review the outcomes of my efforts. The command I ...

What are some effective ways to manage repetitive HTML elements like headers and footers in Angular 4?

Within my Angular web project, I find myself using a variety of different headers on multiple pages. Is there a way to streamline this process by coding the header and footer once and having them automatically included in one or more pages? I am looking ...

Is it possible to apply two ngClass directives to a single div element in Angular 4?

When I click to start editing, a component is called for the editing process. In this component, I am unable to click on anything and the background turns black, which is okay. However, I would like for each ID that I select to edit to become active with a ...

Encountering memory leaks and displaying repetitive data due to having two distinct observables connected to the same Firestore

I am currently utilizing @angular/fire to retrieve data from firestore. I have two components - one serving as the parent and the other as the child. Both of these components are subscribing to different observables using async pipes, although they are bas ...

This error message in AngularJS indicates that the argument 'fn' is not being recognized as a function

I am currently working with angularjs and typescript and I am attempting to create a directive in the following manner: Below is my controller : export const test1 = { template: require('./app.html'), controller($scope, $http) { ...

Utilizing external applications within Angular applications

I have the task of creating a user interface for clocker, a CLI-based issue time tracker. Clocker functions as a stand-alone node.js application without any programming interface. To begin tracking time for an issue labeled 123, the command would typically ...

Conditional generic type in return type with Typescript

How can I condition the generic return type when a value is not present? type Foo = {}; class Bar<P extends Foo> { static make<P extends Foo>(a?: P): Bar<P> { return new Bar(); } } Bar.make() // returns Bar<Foo> ...

Angular 6 implement a waiting function using the subscribe method

I need to make multiple calls to a service using forEach, where each call depends on the completion of the previous one. The code is as follows: itemDefaultConfiguration.command = (onclick) => { this.createConfiguration(configuration.components); ...