0

wait for asynchronous functions to finish in Angular My component "ship-list" wants to get the list from the backend server. So, I made a Service (config.service.ts)

import { Injectable, OnInit } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class ConfigService {
    url = 'http://192.168.1.26:8080/';
    constructor(private http:HttpClient) { }
    async getShipList() {
        this.url = this.url + 'ships';
        this.http
            .get<any[]>(this.url)
            .subscribe(
                (response) => {
                    console.log("Response : ", response);
                    return (response);
                },
                (error) => {
                    console.log("Error ! : " + error);
                }
            );
    }
}

Then, in my component, in the ngOnInit, i call for this function and wait for the results :

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { faCartArrowDown } from '@fortawesome/free-solid-svg-icons';
import { faChartArea } from '@fortawesome/free-solid-svg-icons';
// Services :
import { ConfigService } from '../config/config.service';

@Component({
  selector: 'app-ship-list',
  templateUrl: './ship-list.component.html',
  styleUrls: ['./ship-list.component.scss']
})
export class ShipListComponent implements OnInit {
    // Icons
    faChartArea = faChartArea;
    faCartArrowDown = faCartArrowDown;
    // Var
    searchText: any;
    shipList: any;
    url = this.configService.url;
    
    constructor(private http:HttpClient, private configService: ConfigService) { }

    async ngOnInit() {
        this.shipList = await this.configService.getShipList();
        console.log(this.shipList);
    }
    

}

The problem is, my component doesn't really wait for my service to get the data. I can't find out what I did wrong.

Thank you in advance for your help !

IndrOp
  • 3
  • 1
  • 4

2 Answers2

0

You no need use additional promise:

getShipList(): Observable<any> {
        this.url = this.url + 'ships';
       return this.http.get<any[]>(this.url);            
    }

******
ngOnInit() {
   this.configService.getShipList()
     .subscribe(res => {
        this.shipList = res
      });
    }
V.Tur
  • 1,115
  • 9
  • 20
0

JS is asynchronous and will never wait for any asynchronous call to get complete. So The view gets rendered before the service returns the data. You have implemented the right mechanism, though it is missing few things. Do below changes :

  1. Add return in the service method :

    return this.http .get<any[]>(this.url)

  2. I am assuming you must be rendering the list using *ngFor , So its always a good practice to initilize the array which is used by *ngFor :

    shipList: any[] = [];

the whole code :

async ngOnInit() {
        this.shipList = await this.configService.getShipList().subscribe((result)=>{
        this.shipList = result
        })
}

the service :

 getShipList() {
        
        this.url = this.url;
        return this.http
            .get<any[]>(this.url)
    }

here is the example : demo

programoholic
  • 4,830
  • 5
  • 20
  • 59
  • Hello, i tried what you said and get the following error: ERROR in src/app/ship-list/ship-list.component.ts:25:58 - error TS2339: Property 'subscribe' does not exist on type 'Promise>'. – IndrOp Sep 25 '20 at 12:31