How to assign value to interface property from http/async call in Angular?

Viewed 745

I have a service that returns a JSON object and I want to assign this data to an interface property. Here is the following code, the component.ts code here has been stripped down to contain only the relevant parts.

Service.ts file

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class ApiService {
  constructor(private httpClient: HttpClient) { }

  public getFanSpeed(){
    return this.httpClient.get('http://localhost:4000/auth/get-fan-speed');
  }
}

Component.ts file

import { Component, OnInit } from '@angular/core';
import { ApiService } from '../../api.service';

interface CardSettings {
  content: string;
}

@Component({...})
export class DashboardComponent implements OnInit {
  fanSpeed: string;

  ngOnInit() {
    this.apiService.getFanSpeed().subscribe((response)=>{
      this.fanSpeed = response['fanSpeedVar'];
    });
  }

  fanSpeedCard: CardSettings = {
    content: this.fanSpeed
  };

  constructor(private apiService: ApiService) {}
}

I put a console.log inside the ngOnInit() function and I can see the correct value but for some reason it's just not getting assigned properly to the interface property, hence is just empty in the UI. Any guidance will be appreciated, thank you.

2 Answers

In your code the fanSpeedCard is a property that is assigned value of object (with CardSettings interface) at your class (DashboardComponent) construction time:

fanSpeedCard: CardSettings = {
    content: this.fanSpeed
};

Since fanSpeed is initially not defined (only type as string) and since you are not updating CardSettings object inside API response - your UI does not change.

As mentioned in the comment you need to make sure you update the value of the CardSettings' content property inside the subscribe block (not just fanSpeed):

gOnInit() {
    this.apiService.getFanSpeed().subscribe((response)=>{
      this.fanSpeed = response['fanSpeedVar'];
      this.fanSpeedCard.content = this.fanSpeed;
    });
}

You didn't correctly update fanSpeedCard's content porperty value in ngOnInit(). In ngOnInit() you reassigned the this.fanSpeed value. Here you should assign the service response value to fanSpeedCard's content property.

The following solution will solve your issue.

Component.ts file

import { Component, OnInit } from '@angular/core';
import { ApiService } from '../../api.service';

interface CardSettings {
  content: string;
}

@Component({...})
export class DashboardComponent implements OnInit {
  fanSpeed: string;

  ngOnInit() {
    this.apiService.getFanSpeed().subscribe((response)=>{
      this.fanSpeed = response['fanSpeedVar']
      this.fanSpeedCard.content = this.fanSpeed;
    });
  }

  fanSpeedCard: CardSettings = {
    content: this.fanSpeed
  };

  constructor(private apiService: ApiService) {}
}
Related