For more tips like this, sign up to the weekly newsletter!

How to detect no elements in an RxJS stream

An RxJs Obeservable's subscribe gets 3 callbacks:

  • When an element is emitted
  • When there is an error
  • And when the stream is finished
.subscribe(
  (element) => ...,
  (error) => ...,
  () => ...
)

How to know if there were no elements in the stream?

My first thought was to use an operator that works in a different way when a stream emits elements than if it isn't. One such operator is first, which returns an element if there is one, and an error in case of an empty stream.

.pipe(rxjs.operators.first())
.subscibe(
  () => // non-empty,
  () => // empty
)

Note: You can also use last, which works the same, but emits when the stream is completed.

But alas, what if there is an error coming from the stream itself?

rxjs.throwError("Other error")
  .pipe(rxjs.operators.first())
  .subscribe(undefined, (e) => {
    // Error or empty?
  });

In this case, there is no clear distinction between an error coming in the stream and the no-elements scenario.

Use reduce to emit a boolean

Use true as the initial value, but return false in the iteratee:

.pipe(rxjs.operators.reduce(() => false, true))
.subscribe(
  (isEmpty) => ...
)

In this case, any errors are passed through, and a single boolean will be emitted when the stream finishes. In effect, it provides a reliable way to check if a stream emits elements or not.

Try it
Learn more: