
The RxJS elementAt operator emits a single value at the specified index i of a sequence of values emitted by the source. If there is no value at the index i an error notification ArgumentOutOfRangeError is emitted.
RxJS elementAt returns a value and completes
As the elementAt only delivers a single value, it completes after its first notification. The result$ Observable below, therefore, emits the value 2 and completes at the same time.
const result$ = of(0,1,2,3,4).pipe(
elementAt(2),
);
expectObservable(result$).toBe('(a|)', {'a': 2});
An error notification is emitted by elementAt if no element is found
When looking for an element at the index i, but the source completes before the i-th emission, an error is thrown. This can be demonstrated easily by using RxJS marbles:
const result$ = of(0,1,2,3,4).pipe(
elementAt(5),
);
expectObservable(result$).toBe('#', null, new ArgumentOutOfRangeError());
Use a default value to prevent the ArgumentOutOfRangeError
You can prevent the ArgumentOutOfRangeError. Either make sure the source Observable always delivers as many values as you expect. Or provide a default value as a second parameter to elementAt:
const result$ = of(0,1,2,3,4).pipe(
elementAt(5, 99),
);
expectObservable(result$).toBe('(a|)', { a: 99 });
Exercise for the RxJS elementAt operator 💪
For an element with an ID hideByClick:
- change the element’s background color to grey after clicking once on it
- hide the element completely after clicking a second time on it
<!DOCTYPE html>
<head>
<script src="../../../node_modules/rxjs/dist/bundles/rxjs.umd.js"></script>
</head>
<body>
<div id="hideByClick" style="background: red; height: 300px; margin-bottom: 100px; display: block;"></div>
<script>
const elementAt = rxjs.elementAt;
const fromEvent = rxjs.fromEvent;
const element = document.getElementById('hideByClick');
const clickEvents$ = fromEvent(element, 'click');
</script>
</body>
As always the code examples can be found on GitHub.