Convert a Stream into a Subject

Sometimes you may want to make a RxJS Subject acts like a Stream. Or in another word, you want to encapsulate a stream into a Subject. For example:

const todoEntryPoint$ = createEntryPoint('/todos')

todoEntryPoint$.subscribe(todos => {
  // Return the todo list fetched from the http entry point
})
todoEntryPoint$.next()

How can it be?! Actually, RxJS Subject has already done that:

const increased = new Subject().pipe(map(number => number + 1))

increased.subscribe(val => console.log(val)) // Output: 2
increased.next(1)

So with the entry point example, here is the implementation:

const createEntryPoint = api =>
  new Subject().pipe(
    switctMap(() => ajax.get(api)),
    share() // Optimize the shared stream
  )

Browser History

One example application of this technique is to create a browser history API in RxJS. For example we want that everytime we push a new action into the history Subject, we want it to perform the action on the wrapped history, then notify the subscribers with the new value. The most important thing is that we want to encapsulate all these behaviors into one single object. How would we do that?

To do this, we need some advance knowledge of how to create a custom operator in RxJS. First, we need a type class to wrap our history object. I will call it the HistoryProxy:

The call method wil be called when we pass the operator to Subject.pipe. To preserve source as a Subject we use source.lift so the final instance of the operator will look like this:

And now, we already have our own version of history api in RxJS:

However, in React Epic you will only need to do this either:

Http Entry Points

It's trivial to create a Subject attached to an operator or a list of operators. However, when you have a ton of Subjects and methods like http entry points and you will soon tired of creating subject and rewriting operators. It's time we need an entry point generator:

Last updated

Was this helpful?