RxJS Mastery – #50 skip

RxJS Mastery lesson title skip operator

The RxJS skip operators skip some values based on a count, notifier Observable, or predicate. Besides the basic skip, it comes in additional flavors like skipLast, skipUntil & skipWhile.

RxJS skip skips the first n values

The skip operator accepts a single parameter count of type number. This count defines how many values from the source Observable are skipped. In the example below we have an interval source Observable restricted by take(5). This means the values 0, 1, 2, 3, and 4 are delivered. If we apply skip(2) then the first two numbers 0 and 1 are ignored:

const result$ = interval(1).pipe(
    take(5),
    skip(2)
);

expectObservable(result$).toBe(
    '---ab(c|)',
    { a: 2, b: 3, c: 4 }
);

Of course the values of the result$ Observable are only arriving after 3 time frames.

RxJS skip can ignore all values

Contrary to the RxJS documentation, skip doesn’t raise an error if the skip count is equal to or greater than the actual number of values. It just results in an Observable without any values.

const result$ = interval(1).pipe(
    take(5),
    skip(5)
);

expectObservable(result$).toBe('-----|', null);

RxJS skipLast ignores the last n values

The skipLast(n) works from the opposite direction compared to the basic skip. It ignores a specific number of values before the completion of the source. This also means that the emissions are delayed. Values are buffered and only emitted when they are not part of the last values. This means for skipLast(3) we have to wait until the fourth value arrives from the source. If this fourth value arrives we’re sure that the very first value isn’t skipped. So, this first value is delivered.

In the below example, we want to skip the last 2 values. This means the first value, i.e. 0, can be delivered as soon as the 3rd value from the source arrives. The emission of the value 2 happens at the same time as the completion.

const result$ = interval(1).pipe(
    take(5),
    skipLast(2)
);

expectObservable(result$).toBe(
    '---ab(c|)',
    { a: 0, b: 1, c: 2 }
);

RxJS skipUntil works with a notifier Observable

The skipUntil operator skips values until the first emission of the passed notifier Observable. This can be useful if you want to wait until a second operation has finished, e.g. a user interaction or HTTP request.

In the below example, we define a notifier$ as an operation returning a response after 3 time frames. So, when the notifier$ is used in the skipUntil operator the emission of the source (here interval) starts when the notifier has delivered its first value.

const notifier$ = cold('---r', { r: 'response' });

const result$ = interval(1).pipe(
    take(5),
    skipUntil(notifier$)
);

expectObservable(result$).toBe(
    '---ab(c|)',
    { a: 2, b: 3, c: 4 }
);

RxJS skipWhile works with a predicate too

When you want to skip values while a predicate holds true, then skipWhile is your operator. So, the same effect as in the other example we can reach with a predicate:

const result$ = interval(1).pipe(
    take(5),
    skipWhile(x => x < 2)
);

expectObservable(result$).toBe(
    '---ab(c|)',
    { a: 2, b: 3, c: 4 }
);

Once the predicate holds true, no values are skipped anymore. Even when in above example a number would arrive that is lower than 2, it would be part of the result$ Observable’s values after the predicate was evaluated to true. So, please note that skipWhile is different to filter.

Exercise for the RxJS skip operator 💪

Implement the skip behavior by using the filter operator.

This post is part of the RxJS mastery series. As always the code examples can be found on GitHub.