RxJS Mastery – #45 first

RxJS Mastery lesson title first operator

The RxJS first operator only emits the first value emitted by the source Observable. It also is able to emit only the first value satisfying a condition.

RxJS first emits the first value and completes

Let’s see a simple example with a stream of 6 values coming from interval:

const result$ = interval(1).pipe(
    take(6),
    first(),
);

expectObservable(result$).toBe('-(a|)', { a: 0 });

As you can see in the assertion the result$ Observable just emits the value ‘0’ and completes at the same time.

RxJS first takes first value that fulfills a condition

The common usage is first without any parameters. But you’re also allowed to pass a predicate such that the value you are emitting is matching a condition.

const result$ = interval(1).pipe(
    take(6),
    first(v => v % 2 === 1),
);

expectObservable(result$).toBe('--(a|)', { a: 1 });

When you take the example from above and add a predicate to only consider odd numbers, the Observable will finally emit the single value ‘1’. Not only a predicate can be passed, but also a BooleanConstructor.

RxJS first throws an error if there is no value

If the first operator is not able to emit any value, the subscriber is notified by an EmptyError. This can happen for the case with as well as without predicate. In the following example the numbers from 0 to 5 are delivered by the source, but first only considers a value above 5. Hence, an EmptyError is returned after 6 time frames. At this time the source has completed and first knows that no other value is going to arrive.

const result$ = interval(1).pipe(
    take(6),
    first(v => v > 5),
);

expectObservable(result$).toBe('------#', null, new EmptyError());

For the take operator the behavior is different. A take(1) is not notifying with an error if there is no value.

RxJS first accepts a default value

You can prevent the EmptyError by passing a default. For no value the > 5 condition is true. Therefore the default value ’99’ is considered.

const result$ = interval(1).pipe(
    take(6),
    first(v => v > 5, 99),
);

expectObservable(result$).toBe('------(a|)', { a: 99 });

Exercise for the RxJS first operator 💪

Given the Observable defined by the of operator below, emit the first value that evaluates to true:

of(null, undefined, '', false, 0, {}, 1, true)

As always the code examples can be found on GitHub.