VWeber
VWeber

Reputation: 1261

Angular 6 HTTPClient and Observable

I'm trying to load the following structure from a HTTP endpoint:

{
  "dbHeartbeats": [
    [
      {
        "size": [
          "2113464 documents"
        ],
        "buildInfo": [
          "4.0.0"
        ],
        "heartbeat": [
          true
        ],
        "name": [
          "MongoDB"
        ]
      },
      {
        "size": [
          "8549 kB"
        ],
        "buildInfo": [
          "PostgreSQL 10.4 (Debian 10.4-2.pgdg90+1)"
        ],
        "heartbeat": [
          true
        ],
        "name": [
          "PostgreSQL Database"
        ]
      }
    ]
  ]

So I wrote two interfaces:

export interface DbHeartbeats {
  name: string;
}

and

import { DbHeartbeats } from "./db-heartbeats";

export interface Heartbeats {
  dbHeartbeats: DbHeartbeats;
}

A simple service that calls the endpoint and returns an observable:

import { Injectable } from '@angular/core';
import { Heartbeats } from './heartbeats';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';


@Injectable({
  providedIn: 'root'
})
export class HeartbeatService {
  heartbeats$: Observable<Heartbeats>;
  apiRoot = 'http://localhost:9090/backend/rest/v1/heartbeat';

  constructor(private httpClient: HttpClient) {
    this.heartbeats$ = this.getHeartbeats();
  }
  getHeartbeats() {
    return this.httpClient.get<Heartbeats>(this.apiRoot);
  }
}

and a template

<div style="text-align:center">
  <div *ngFor="let item of (heartbeatService.heartbeats$ | async).dbHeartbeats">
    Test {{item.name}}
  </div>
</div>

import {Component} from '@angular/core';
import {HeartbeatService} from './heartbeat.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  constructor(public heartbeatService: HeartbeatService) {
  }
}

But I always get the error message 'Cannot read property 'dbHeartbeats' of null'. It's driving me nuts, I don't get what I'm doing wrong here. Any advices?

Upvotes: 1

Views: 830

Answers (1)

Kabb5
Kabb5

Reputation: 3870

Based on the data sample you provided, you should define your interfaces like this:

export interface DbHeartbeats {
  size: string;
  buildInfo: string;
  heartbeat: boolean;
  name: string;
}

export interface Heartbeats {
  dbHeartbeats: Array<DbHeartbeats>;
}

Then your getHeartbeats function will return the Observable<Heartbeats> you expect.

Upvotes: 1

Related Questions