31

Here is what I'm doing now to convert an Observable to a ReplaySubject:

const subject = new Rx.ReplaySubject(1);

observable.subscribe(e => subject.next(e));

Is this the best way to make the conversion, or is there a more idiomatic way?

BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
Misha Moroshko
  • 166,356
  • 226
  • 505
  • 746
  • 3
    I suppose you could do `observable.subscribe(subject.next)` if you really want to shave characters. But why do you need to create the subject if you have the observable? If you just want the replay functionality, use the [`Observable.replay`](http://reactivex.io/documentation/operators/replay.html) method. – jonrsharpe Jan 18 '17 at 22:31
  • 1
    Actually you can even do `observable.subscribe(subject)`, without the `.next`) just note that once the observable completes, so does the subject. – Meir Jan 19 '17 at 07:26
  • 2
    @jonrsharpe `Observable.replay` doesn't seem to be available in RxJS v5. – Misha Moroshko Jan 19 '17 at 16:20
  • 3
    For RxJS version 6.4.0 this will do the trick: `observable.pipe(shareReplay(1))`, which is equivalent (as of 6.4.0) to `observable.pipe(shareReplay({ bufferSize: 1, refCount: false }))`. For gory details on `refcount` look here: https://blog.angularindepth.com/rxjs-whats-changed-with-sharereplay-65c098843e95 – Andrei Sinitson Aug 31 '19 at 19:04
  • docs for above shareReplay comment here https://www.learnrxjs.io/operators/multicasting/sharereplay.html – DKebler Jan 03 '20 at 17:58

3 Answers3

25

You can use just observable.subscribe(subject) if you want to pass all 3 types of notifications because a Subject already behaves like an observer. For example:

let subject = new ReplaySubject();
subject.subscribe(
    val => console.log(val),
    undefined, 
    () => console.log('completed')
);

Observable
    .interval(500)
    .take(5)
    .subscribe(subject);

setTimeout(() => {
    subject.next('Hello');
}, 1000)

See live demo: https://jsbin.com/bayewo/2/edit?js,console

However this has one important consequence. Since you've already subscribed to the source Observable you turned it from "cold" to "hot" (maybe it doesn't matter in your use-case).

kolypto
  • 31,774
  • 17
  • 105
  • 99
martin
  • 93,354
  • 25
  • 191
  • 226
9

It depends on what do you mean by 'convert'.

If you need to make your observable shared and replay the values, use observable.pipe(shareReplay(1)).

If you want to have the subscriber functionality as well, you need to use a new ReplaySubject subscribed to the original Observable observable.subscribe(subject);.

Dmitriy Kachko
  • 2,804
  • 1
  • 19
  • 21
-1

Like the first answer, as subject is also an observer.

const subject = new Rx.ReplaySubject(1);
observable.subscribe(subject);