Using promises and observables together?

Hi All,

I’m using a number of promises to perform various SQL transactions within my app. I am also using Angulars latest http library to perform http.get and http.post. These methods, however, return observables which use a different set of callbacks, than those provided with promises.

My question is, is it possible to wrap the http observables as promises. The reason I ask is because currently, at my apps first launch, I wish to

  1. Create tables (using promises)
  2. Fetch data (using observables)
  3. Write data to db (using promises)
  4. Return a status when all of this is finished.

If step 2 returned a promise, I could simply use the .then() syntax to order these asyncronous tasks, however, since task 2 returns an observable, I am unsure how to maintain order between the promises and observables.

Has anyone else faced this issue, or know of a solution?

Thanks all!

You could convert an Observable to Promise using toPromise():

import 'rxjs/operator/add/toPromise';
// ...
export class SomeService {
  // ...
  getSomething() {
    // Returns a Promise instead of Observable.
    return this.http.get(/* ... */)
      // more code...
      .toPromise();
  }
  // ...
}

@iignatov Thanks for getting back so quickly. I was just reading this on stackoverflow: http://stackoverflow.com/questions/36777284/angular-2-convert-observable-to-promise

Didn’t realise it would be so easy to swap out, I had expected a horribly complex workaround. Thank you for help.

2 Likes

But if you using that in order to show data in the screen don’t forget to use the async pipe in the html if you are using async await { data | async }

I am just leaving this here for the google-searchers.

1 Like

or better yet just use the observables, I believe it is a lot faster than using .toPromise() of the http class.

Yep! I’ve opted for Observables for pretty much everything these days. Back in May '16 this was during the transition of what was recommended. Observables are great

My current thinking is that Observables have less overhead if you need to listen to a stream that might change. Promises have less overhead if you need to ask a question at most once in an execution. Example of the second: are there login credentials already locally stored on the device?

Edit: also, the conversation should really include three things; Promises, Observables, and Subjects. I use BehaviorSubject a lot in providers, and pages subscribe to them.

1 Like

I think ReplaySubject should also be in the conversation, when there is not a clearly-defined initial state, as is needed for BehaviorSubject.

I’ve never used ReplaySubject. I just start B Subject with a null value. Can you give me a thought experiment (or a real situation) where my way is inferior? (Also, while I’m at it, have you ever used AnonymousSubject? I haven’t.)

As you are probably well aware, I do not pull punches, but even for me, “inferior” is stronger than I would use here.

User authentication is the first idea that comes to mind. I find having a tri-state Subject (as ReplaySubject) is helpful here. I am authenticated, or I am not authenticated, or I don’t know yet. Subscribing to a ReplaySubject means I only have to think about concrete known states: my subscription handler does not have to concern itself with the “unknown” state that a subscriber to a BehaviorSubject initialized with null would have to.

1 Like

Just for my own clarity, by tri-state, do you mean the states of the listener?

  1. most recently heard true
  2. most recently heard false
  3. has not heard anything yet
1 Like

Precisely. I don’t think a BehaviorSubject has (3), which I find occasionally useful.

1 Like

After sleeping on it, I think a key issue might be that I’ve only dealt with situations where all kinds of falsy are handled the same. Where the difference might matter a lot is when I would need to differentiate from “hasn’t heard yet” and “heard a value of null or other falsy” – so user auth might not be best example, since the consequences of no information and falsy information are usually the same: display the page as though no one is logged in. But listening to an exterior stream that sometimes emits null/falsy values might require ReplaySubject.

Not necessarily. Generally, I want to treat “no information” differently from “confirmed false” when it comes to authentication. In a “no information” state, I want to show a loading indicator until we know one way or another. I prefer that to sending authenticated users (who we aren’t sure about during an initial check) to a login/registration screen and then having that flicker to a dashboard.

1 Like