What is the best way to display data retrieved from an httpClient.get() call in Angular?

My goal is to fetch data from an external API and display it, but I'm encountering an issue where the data seems to be retrieved "too late" in my code. This delay may be caused by the asynchronous nature of HttpClient.get().

1) Service:

getMetroListObservable(): Observable<Metro[]> {
  return this.http.get(this.api)
    .map(this.mapper)
    .catch(this.handleError);
  }

  private mapper(current) {
    console.log(current); // Data appears here
    return current as Metro[];
  }

  private handleError(error: any) {
    return Observable.throw(error.message || error);
  }

2) Component using the service:

constructor(private service: MyserviceService) {
    this.metroList = [];
  }

  ngOnInit() {
    this.getMetroListObservable();
    console.log(this.metroList); // Returns empty array
    this.metro = this.metroList[0];
  }

  getMetroListObservable() {
    this.service.getMetroListObservable()
      .subscribe(
        response => this.metroList = response,
        error => this.errorMsg = error
      );
  }

3) Template for the component:

<p>element: {{metro.idt}}</p>

I want to display the first element of the "metroList" array, but it's currently null because the array is empty. How can I resolve this issue?

Thank you in advance

Answer №1

Utilize the async pipe instead of subscribing to avoid manual unsubscription. Implement it like this: import {Observable} from 'rxjs';

metroList: Observable<Metro[]>

constructor(private service: MyserviceService) {
  this.metroList = this.service.getMetroListObservable();
}

Then, render it in your template like this:

<p>element: {{(metroList | async)[0]?.idt}}</p>

Answer №2

Revise this

  getListaMetroObservable() {
    this.service.getListaMetroObservable()
      .subscribe(
        risp => this.listametro = risp,
        error => this.errorMsg = error
      );
  }

Transform into the following:

  getListaMetroObservable() {
    this.service.getListaMetroObservable().subscribe(result=>{
         console.log(result)
         this.listametro = result
      },error=>{
         console.log(error);
       });
  }

Inquire about what can be seen in this line console.log(result)

Answer №3

When you call ngOnInit(), the code inside it will not wait for the code inside subscribe() to finish executing. This is why nothing is being printed in your console.

The same applies when you assign this.metro outside of the subscribe(). Even if you do it after calling getListaMetroObservable(), it won't wait for the subscription to complete.

You can try restructuring your code like this:

  getListaMetroObservable() {
    this.service.getListaMetroObservable()
      .subscribe(
        response => 
        {
          this.listametro = response;
          console.log(this.listametro);
          this.metro = this.listametro[0];
        },
        error => this.errorMsg = error
      );
  }

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

The preflight request fails to meet the access control requirements

Having trouble making a JWT authorized json rest api request from my angular 8 web application, leading to the error mentioned above. I have followed all sensible CORS configuration steps, even relaxing the rules to no avail. Seeking help from you guys now ...

Dealing with asynchronous operations in a pipeline with fp-ts

I'm currently exploring fp-ts and have been contemplating how to restructure my functions in order to steer clear of nested folds. While many online examples showcase a clean invocation of the pipe function, I am struggling to eliminate the nested fol ...

Implementing ngClass with a dynamic ID in the URL condition

I am attempting to create an ngClass condition that adds an active class to a list element. Specifically, I want it to work for both the URLs '/companies' and '/company/:id'. The issue I am facing is that the current setup does not fun ...

Error in Typescript: An element is implicitly assigned the 'any' type because a string expression is being used to index a different type

Hello everyone, I'm fairly new to TypeScript and I've been struggling to troubleshoot an error in my code. Can someone please assist me with solving this TypeScript error? I keep getting the error message: "Element implicitly has an 'any&a ...

What is the process for transforming a string literal type into the keys of a different type?

Imagine having a string literal type like this: type Letters = "a" | "b" | "c" | "d" | "e"; Is there a way to create the following type based on Letters? type LetterFlags = {a: boolean, b: boolean, c: bool ...

Modify the variable's value depending on a different variable's value

When "a" changes in the example below, I would like "b" to also change. Currently, I am utilizing a method that utilizes the onfocusout function to capture the change event of the "a" input. Is there an alternative built-in way to achieve this? @Compone ...

Integrate AngularJS service with Angular framework

Attempting to utilize the $log service within an angular 2 app, it seems that the following steps are necessary: Set up a module that includes the service you wish to inject. Utilize UpgradeAdapter's upgradeNg1Provider method. Therefore, I proceede ...

Acquire data through Reactive Form input

Struggling to populate my entity data in a reactive form. Data retrieval is successful, but unsure about the ideal method and timing for filling out the form with these values. Here's the structure of my form: import { Component, OnInit, Input } fr ...

An uncaught security error occurred when attempting to execute the 'pushState' function on the 'History' object

Here are the routes in my application: const routes:Routes =[ {path:'', component:WelcomeComponent}, {path:'profile', component: ProfileComponent}, {path:'addcourse', component: AddcourseComponent}, {path:'course ...

Breaking down and setting default values for constructor attributes

Can Typescript support a structure similar to this? class Currency { last_updated: number; constructor(public { id: string, name: string }) {} } So that the class Currency can accept an object with properties like id: string, name: string and automa ...

What is the best way to integrate Angular into my existing *ngFor loop?

Within this code segment, I am attempting to display testRecords on the screen, which are test records. However, even though there exist test records, the ngFor loop is not being entered. {{testRecords}} <div class="row mb-2" *ngFor="let ...

Using a single TypeORM connection across various modules in NestJS

In the process of developing a link shortener, I have set up a CRUD REST API for authentication and creating shortened links. Now, I am looking to manage redirects for these shortened URLs without using the same path as my API endpoints (e.g. /api/v1/). Af ...

Combining the JSON code coverage reports generated by both Cypress and Karma does not yield an accurate outcome

In my angular project, I am testing it using the built-in unit testing tool (karma) and Cypress. My goal is to combine the code coverage reports from both tests. I have successfully set up the coverage configurations and merged the outputs using `nyc merg ...

The text inside the Mapbox GL popup cannot be highlighted or copied

I'm encountering an issue where the text in my popups is unselectable. Even though I can close the popups through various methods, such as clicking on them, the pointer remains as a hand icon when hovering over the text and doesn't change to the ...

Navigating session discrepancies: Combining various social media platforms using Next.js and NextAuth

Recently, I ran into a problem where, upon logging in with Google, I found myself needing access tokens for Twitter and LinkedIn to send out API requests. The issue came about when NextAuth modified my session data to be from either Twitter or LinkedIn ins ...

After the component has been initialized for the second time, the elementId is found to be null

When working with a component that involves drawing a canvas chart, I encountered an issue. Upon initializing the component for the first time, everything works fine. However, if I navigate away from the component and return to it later, document.getElemen ...

Incorporate TypeScript @types/ packages within the packages.json file

I have a question about the @types dependencies in the package.json file: According to the information provided in this URL, it is suggested to install types as runtime dependency npm install --save @types/lodash TS 2.x d.ts Consumption However, personal ...

Encountered issue in Angular: Object prototype must be either an Object or null, not undefined

I encountered an issue with my Angular application when trying to install npm dependencies using npm i. I kept receiving a "sha1 seems to be corrupted" error. To resolve this, I deleted the package-lock.json file and was able to successfully install all th ...

Display content from the observable data$ only if it is available, otherwise show a default message

I am looking to display a block only if it has data retrieved from the server; otherwise, I want to display a 'No content found' block. <ng-container *ngIf="data$ async as data && data.payload; else noContent"> {{data.payload | jso ...

The specified Observable<Response> argument cannot be assigned to the parameter of type Observable<Response> at hand

Confused... React, Gulp private performAction(inputValue: Observable<Response>) { ... } ... triggerAction() { performAction(this.http.get(...)) } ...