I have a parent observable that, once it has a subscriber, will do a lookup and emit a single value, then complete.
I'd like to convert that into an observable (or behavior subject or whatever works) that does the following: once it has at least one subscriber, it gets the result from the parent observable (once). Then it emits that value to all of its subscribers, and also emits that single value to all future subscribers, when they subscribe. It should continue with this behavior even if its subscriber count drops to zero.
It seems like this should be easy. Here is what didn't work:
theValue$: Observable<boolean> = parent$
.take(1)
.share()
Other things that didn't work: publishReplay()
, publish()
. Something that worked better:
theValue$ = new BehaviorSubject<boolean>(false);
parent$
.take(1)
.subscribe( value => theValue$.next(value));
There is a problem with this approach, though: parent$
is subscribed to before theValue$
gets its first subscriber.
Is there a better way to handle this?
shareReplay
should do what you want:
import 'rxjs/add/operator/shareReplay';
...
theValue$: Observable<boolean> = parent$.shareReplay(1);
shareReplay
was added in RxJS version 5.4.0. It returns a reference counted observable that will subscribe to the source - parent$
- upon the first subscription being made. And subscriptions that are made after the source completes will receive replayed notifications.
shareReplay
- and refCount
in general - is explained in more detail in an article I wrote recently: RxJS: How to Use refCount.