Convert Promise to Observable

try this:

import 'rxjs/add/observable/fromPromise';
import { Observable } from "rxjs/Observable";

const subscription = Observable.fromPromise(
    firebase.auth().createUserWithEmailAndPassword(email, password)
);
subscription.subscribe(firebaseUser => /* Do anything with data received */,
                       error => /* Handle error here */);

you can find complete reference to fromPromise operator here.


1 Direct Execution / Conversion

Use from to directly convert a previously created Promise to an Observable.

import { from } from 'rxjs';

// getPromise() is called once, the promise is passed to the Observable
const observable$ = from(getPromise());

observable$ will be a hot Observable that effectively replays the Promises value to Subscribers.

It's a hot Observable because the producer (in this case the Promise) is created outside of the Observable. Multiple subscribers will share the same Promise. If the inner Promise has been resolved a new subscriber to the Observable will get its value immediately.

2 Deferred Execution On Every Subscribe

Use defer with a Promise factory function as input to defer the creation and conversion of a Promise to an Observable.

import { defer } from 'rxjs';

// getPromise() is called every time someone subscribes to the observable$
const observable$ = defer(() => getPromise());

observable$ will be a cold Observable.

It's a cold Observable because the producer (the Promise) is created inside of the Observable. Each subscriber will create a new Promise by calling the given Promise factory function.

This allows you to create an observable$ without creating and thus executing a Promise right away and without sharing this Promise with multiple subscribers. Each subscriber to observable$ effectively calls from(promiseFactory()).subscribe(subscriber). So each subscriber creates and converts its own new Promise to a new Observable and attaches itself to this new Observable.

3 Many Operators Accept Promises Directly

Most RxJS operators that combine (e.g. merge, concat, forkJoin, combineLatest ...) or transform observables (e.g. switchMap, mergeMap, concatMap, catchError ...) accept promises directly. If you're using one of them anyway you don't have to use from to wrap a promise first (but to create a cold observable you still might have to use defer).

// Execute two promises simultaneously
forkJoin(getPromise(1), getPromise(2)).pipe(
  switchMap(([v1, v2]) => v1.getPromise(v2)) // map to nested Promise
)

Check the documentation or implementation to see if the operator you're using accepts ObservableInput or SubscribableOrPromise.

type ObservableInput<T> = SubscribableOrPromise<T> | ArrayLike<T> | Iterable<T>;
// Note the PromiseLike ----------------------------------------------------v
type SubscribableOrPromise<T> = Subscribable<T> | Subscribable<never> | PromiseLike<T> | InteropObservable<T>;

The difference between from and defer in an example: https://stackblitz.com/edit/rxjs-6rb7vf

const getPromise = val => new Promise(resolve => {
  console.log('Promise created for', val);
  setTimeout(() => resolve(`Promise Resolved: ${val}`), 5000);
});

// the execution of getPromise('FROM') starts here, when you create the promise inside from
const fromPromise$ = from(getPromise('FROM'));
const deferPromise$ = defer(() => getPromise('DEFER'));

fromPromise$.subscribe(console.log);
// the execution of getPromise('DEFER') starts here, when you subscribe to deferPromise$
deferPromise$.subscribe(console.log);

defer is probably the operator most people are looking for as many apps rely on Observables to be cold and trigger a data fetch on subscribe. from is still a viable option for certain use cases though, e.g. when you want to create a Promise once during some initialisation process and then propagate its value via an Observable that will be subscribed to multiple times, but don't want to create and execute the Promise again for every subscriber.


If you are using RxJS 6.0.0:

import { from } from 'rxjs';
const observable = from(promise);