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.