Angular 8: Using HttpClient.get.toPromise

Viewed 7702

From a service constructor, I want to call 2 HttpClient.get asynchronously. When the constructor is completed, the 2 get requests have to be already completed.

public async ReadConfiguration () 
  {
      await this.http.get ('http://localhost:80/api/Target.xml',{ responseType: 'text' })
        .toPromise()
        .then(res => console.log(res))
        .catch(err => { console.log ('error');
        });

      console.log ('line 25');

      await this.http.get ('http://localhost:80/api/Target.xml',{ responseType: 'text' })
        .toPromise()
        .then(res => console.log(res))
        .catch(err => { console.log ('error');
        });

      console.log ('line 32');
  }

  /*************************************************************************************/
  constructor(private http: HttpClient) {
    console.log ('-->constructor');
    this.ReadConfiguration ();
    console.log ('Done');
    console.log ('<--constructor');

  }

On the console I got:

-->constructor <br/>
Done <br/>
<--constructor <br/>

and only then (after few constructors are executed) I got the data.

Can you please tell what is wrong in my code ?

Thank you in advance, Zvika

5 Answers

The purpose of using the constructor is to create the component and to initiate the variables

In your case you are looking for what we called it a 'HOOK' as ngOnInit that is executed after the Constructor.

Please look at this : Difference between Constructor and ngOnInit

And For the Synchronicity which may depends on the response time of your API i suggest you to make the two calls as a nested call, i mean one can be inside the other as bellow :

await this.http.get ('http://localhost:80/api/Target.xml',{ responseType: 'text' })
        .toPromise()
        .then(res => {

 await this.http.get ('http://localhost:80/api/Target.xml',{ responseType: 'text' })
        .toPromise()
        .then(res => console.log(res))
        .catch(err => { console.log ('error');
        });

})
        .catch(err => { console.log ('error');
        });

Yes, code is working fine.

Because your method this.ReadConfiguration(); is asynchronous in nature, and it will run out of the normal flow and execute after some time which is working as expected.

if you want to use your readconfiguration function your gonna need to use it like this:

    constructor(private http: HttpClient) {
       console.log ('-->constructor');
       this.ReadConfiguration().then(data => {
       console.log('done')
       console.log ('<--constructor');
       });
    }

and your function maybe something like this:

public async ReadConfiguration () 
  {
      await this.http.get ('http://localhost:80/api/Target.xml',{ responseType: 'text' })
        .toPromise()
        .then(res => console.log(res))
        .catch(err => { console.log ('error');
        });

      console.log ('line 25');

      await this.http.get ('http://localhost:80/api/Target.xml',{ responseType: 'text' })
        .toPromise()
        .then(res => console.log(res))
        .catch(err => { console.log ('error');
        });

      console.log ('line 32');
    Promise.reslove();
  }

As Youssef Tounoussi stated above, put the ReadConfiguration call in async ngOnInit(). In addition, to avoid the nested promise responses, you could rearrange the calls as shown below:

public async ReadConfiguration()
  {
    let res: string; 
    try
    {
      // 1st call
      res = await this.http.get('http://localhost:80/api/Target.xml', { responseType: 'text' }).toPromise();
      console.log(res);

      // 2nd call
      res = await this.http.get('http://localhost:80/api/Target.xml', { responseType: 'text' }).toPromise();
      console.log(res);

    } catch (error)
    {
      console.error(error);
    }
  }

  async ngOnInit()
  {
    // ...
    await this.ReadConfiguration();
    // ..
  }

You need to put an await in this line:

this.ReadConfiguration ();

Like this:

constructor(private http: HttpClient) {
   console.log ('-->constructor');
   await this.ReadConfiguration ();
   console.log ('Done');
   console.log ('<--constructor');
}
Related