25

I have a service that has a method foo. Inside the method I subscribe to an observable (http-client).

foo () : boolean
{
  let ret : false;

  this.http.get ("/blabla").subscribe (
  (resp) =>
  {
    ret = true;
  }

  return ret;
);

I like to return a boolean value from foo() that depends on the get. That is not working because http.get is asynchronous - return is called before http.get finished.

How can I make this synchronous?

Returning the observable instead boolean is not an option here. That is because I handle the response of get in foo (not shown here) but I also need to act out of foo depending on its return.


I extended my sample with pipe and tap. Now I return the http.get-observable for outside the service and I process the http.get-result with tap.

foo () : Observable <any>
{
  return this.http.get ("/blabla").pipe (tap (x => handlehere ()));
}

As far I see, there is only one ugliness with it. I have the complexity of parsing the get-result inside AND outside of foo. I would prefer a simple boolean outside of foo.

7
  • 1
    Possible duplicate of How do I return the response from an asynchronous call? Commented Sep 24, 2018 at 18:27
  • 2
    How can I make this synchronous? <= you don't, you return an observable or a promise. Returning the observable instead boolean is not an option here <= why? Commented Sep 24, 2018 at 18:28
  • 2
    Then you have no option because synchronous code could become asynchronous in one operation, but asynchronous code could never become synchronous again Commented Sep 24, 2018 at 18:29
  • but I also need to act out of foo depending of its return <= then make the acting on the call also occur asynchronously. Once you understand the pattern used for asynchronous javascript (typescript) code/interaction it will be much easier for you to write your application. There is generally a fair amount of asynchronous interaction in applications because they interact with external resources (user input, databases, network streams, etc). You will be a better programmer for it. Commented Sep 24, 2018 at 18:35
  • Returning an Observable would be also possible but then it must be related to http.get. I do not know how to do that. Commented Sep 24, 2018 at 18:35

1 Answer 1

28

This method can only run asynchronously, so you don't have a lot of option. Returning the observable and subscribe or return a promise. Perhaps returning a Promise will suit more your need in terms of comprehension.

In your service, the foo() method:

async foo() {
   const result = await this.http.get("/blabla").toPromise();
   
   // do what you want with result 

   return result;
}

How to call it:

this.myService.foo().then( (result) => {
   // Do what you want with the result
});
Sign up to request clarification or add additional context in comments.

3 Comments

toPromise() is deprecated and will be removed in v8. Anyone found some simillar workaround?
You can use ` firstValueFrom(observable)` instead of toPromise()
this answer is not synchronous in angular. firstValueFrom(observable) is also not synchronous, because you have to await both call's, which means other resources can do stuff while waiting on the result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.