The RxJS range operator creates an Observable to emit a sequence of numbers.
RxJS range explained 🎓
The range operator accepts a start, count and scheduler argument. Start defines the start of the range and count defines the number of emission. After each emission the value is increases by 1.
range(start: number, count?: number, scheduler?: SchedulerLike): Observable<number>
That means if we specify a start number 1 and a count of 5 we get the numbers 1 to 5 as single next notifications:
range(1,5).subscribe({ next: console.log });
// 1
// 2
// 3
// 4
// 5
It also works for non-integer numbers:
range(1.5, 3).subscribe({ next: console.log });
// 1.5
// 2.5
// 3.5
// complete
Importantly, if only one argument is passed then the argument is the count and not the start. The start in this case is set to 0. Hence, the numbers 0 to 4 are emitted in the following case:
range(5).subscribe({ next: console.log });
// 0
// 1
// 2
// 3
// 4
What problems does the RxJS range operator solve? 🚧
The range operator is used whenever you need a sequence of single numbers emitted at the same time. This can be helpful for testing but also in other cases where you need a controlled number of emissions.
How to test the range operator🚦
RxJS marbles also come into play when we want to test code involving the range operator. As the emission happens as single values but at the same time we need to group. Therefore (123|) is used in the marbles diagram indicating that the next and complete notifications happen all at once.
it('should emit with timing', () => {
testScheduler.run((helpers) => {
const { expectObservable } = helpers;
const numbers$ = range(1,3);
expectObservable(numbers$).toBe('(123|)', {'1': 1, '2': 2, '3': 3});
});
});
Exercise for the range operator 💪
Combine the range operator with another time based operator, except interval, to emulate the functionality of the interval operator.