3

I have a service that returns an array of JSON objects that I am attempting to load into an html table. The http get is returning data however the data will not load into the table. I suspect I may have an issue with the data types I am using in my typescript code. This code is logging no errors to the console.

If I comment out the data table and add a new line with {{ myData }} the page displays "function values() { [native code] }"

my-data.component.html

<div class="container-fluid">
  <div class="jumbotron text-center">
    <h1>
      My Data
    </h1>
  </div>
  <div>
    <app-loader [isLoading]="isLoading"></app-loader>
    <table class="table table-hover table-responsive" [hidden]="isLoading">
      <thead>
        <tr>
            <th scope="col" data-field="myData.fileName">File Name</th>
            <th scope="col" data-field="myData.index">Index</th>
        </tr>
      </thead>
    </table>
  </div>
</div>

my-data.component.ts

import { Component, OnInit } from '@angular/core';
import { finalize } from 'rxjs/operators';

import { MyService } from './my-service.service';

@Component({
  selector: 'app-my-data',
  templateUrl: './my-data.component.html',
  styleUrls: ['./my-data.component.scss']
})
export class MyComponent implements OnInit {
  myData: any;
  isLoading: boolean;

  constructor(private myService: MyService) {}

  ngOnInit() {
    this.isLoading = true;
    this.myService
      .getMyData()
      .pipe(
        finalize(() => {
          this.isLoading = false;
        })
      )
      .subscribe((myData: any) => {
        this.myData = myData;
      });
  }
}

my-data.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

const routes = {
  dataEndpoint: 'http://localhost:53452/api/data'
};

@Injectable()
export class MyService {
  constructor(private httpClient: HttpClient) {}

  getMyData(): Observable<any> {
    return this.httpClient
      .cache()
      .get(routes.dataEndpoint)
      .pipe(
        map((body: any) => body.values),
        catchError(() => of('Error, could not load My Data'))
      );
  }
}

JSON Returned from get

[{"fileName":"sometext.txt", "index": 1},{"fileName":"sometext2.txt", "index": 2}]

3 Answers 3

2

Your data is an array, so you have to use *ngFor, like this:

<div class="container-fluid">
  <div class="jumbotron text-center">
    <h1>
      My Data
    </h1>
  </div>
  <div>
    <app-loader [isLoading]="isLoading"></app-loader>
    <table class="table table-hover table-responsive" [hidden]="isLoading">
      <thead>
        <tr *ngFor="let data of myData">
            <th scope="col" data-field="data.fileName">File Name</th>
            <th scope="col" data-field="data.index">Index</th>
        </tr>
      </thead>
    </table>
  </div>
</div>
Sign up to request clarification or add additional context in comments.

2 Comments

This was helpful but the real problem was in the service.
does the service return this data? What does he really return?
2

I believe you are trying to display the data in the table body. Try this.

<div class="container-fluid">
  <div class="jumbotron text-center">
    <h1>
      My Data
    </h1>
  </div>
  <div>
    <app-loader [isLoading]="isLoading"></app-loader>
    <table class="table table-hover table-responsive" [hidden]="isLoading">
      <thead>
        <tr>
            <th scope="col">File Name</th>
            <th scope="col">Index</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let file of myData">
            <td>{{file.fileName}}</td>
            <td>{{file.index}}</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

1 Comment

This was helpful but the real problem was in the service.
0

I had to update the service to fix the problem which involved adding an interface and changing body.values to body. See https://angular.io/guide/http#type-checking-the-response for more information.

Updated my-data.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

const routes = {
  dataEndpoint: 'http://localhost:53452/api/data'
};

export interface MyDataContext {
  FileName: string;
  Index: number;
}

@Injectable()
export class MyService {
  constructor(private httpClient: HttpClient) {}

  getMyData(): Observable<MyDataContext> {
    return this.httpClient
      .cache()
      .get<MyDataContext>(routes.dataEndpoint)
      .pipe(
        map((body: any) => body),
        catchError(() => of('Error, could not load My Data'))
      );
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.