Search code examples
javascriptangularobservableangular-httpclient

Angular: normal array from observable


I've been rewriting an Angular app which previously omitted the use of http requests. For this reason, lots of logic is contained in a service component and the http request was simulated by working with an array of the following format:

[{"name": "somename1", "subset1": [
  {"name": "somesubname1", "subset2": [
    {"somemetric1": 0, "somemetric2: 1, "somemetric3": 2}]}]}]

This is exactly the format which is also displayed on some web api (https://localhost:5001/api/values e.g.).

My service looks like this:

import { Injectable } from '@angular/core'
import { Subject, Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';


@Injectable()

export class StrategyService{

    data:any

    constructor(private httpClient: HttpClient) {
    }

    getData() {
        this.data = this.httpClient.get("https://localhost:5001/api/values")
    }

If I console.log(this.data) in e.g. getData() and call this function when running my app, "undefined" is returned in the console. When I would replace the body of getData() with

this.httpClient.get("https://localhost:5001/api/values").subscribe(data => {data = console.log(data)})

the console does return the array in the format as desired (and displayed in the first block). Console logging is in fact not what I need since I need to be able to access the data in other functions inside my service component which would need array-specific methods such as .find etc.

I feel like this is a simple thing to do, but I've had no succes so far. I've tried

import { Injectable } from '@angular/core'
import { Subject, Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';


@Injectable()

export class StrategyService{

    dat:any

    constructor(private httpClient: HttpClient) {
    }

    getData() {
        this.httpClient.get("https://localhost:5001/api/values").subscribe(data => {this.dat = data})
    }

console.log(this.dat) still returns "undefined".


Solution

  • This is a classic starting problem everyone has with async code. Have a research of rxjs + how async code works in Typescript.

    The solution to your problem is to check the data within the subscribe block as that happens after the response from your api is back.

    this.httpClient.get("https://localhost:5001/api/values").subscribe(data => console.log(data))
    
    public myFunction() {
    this.httpClient.get("https://localhost:5001/api/values").subscribe(data => {
       this.data = data;
       console.log(this.data); // data is defined here
    })
    console.log(this.data); // data will be undefined here
    }
    

    Links to useful resources:
    https://www.learnrxjs.io/
    https://angular.io/guide/http