Skip to content

Commit

Permalink
fix(elementAt): Allow defaultValue of undefined.
Browse files Browse the repository at this point in the history
  • Loading branch information
benlesh committed Mar 3, 2021
1 parent 62a6bbe commit 5bc1b3e
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 12 deletions.
8 changes: 6 additions & 2 deletions spec-dtslint/operators/elementAt-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ it('should enforce types', () => {
const o = of('foo').pipe(elementAt()); // $ExpectError
});

it('should enforce of index', () => {
it('should enforce passing the index', () => {
const o = of('foo').pipe(elementAt('foo')); // $ExpectError
});

it('should enforce of default', () => {
const o = of('foo').pipe(elementAt(5, 5)); // $ExpectError
const o = of('foo').pipe(elementAt(5, 5)); // $ExpectType Observable<string | number>
});

it('should allow undefined default', () => {
const o = of('foo').pipe(elementAt(100, undefined)); // $ExpectType Observable<string | undefined>
});
11 changes: 11 additions & 0 deletions spec/operators/elementAt-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ describe('elementAt', () => {
});
});

it('should allow undefined as a default value', () => {
testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
const e1 = hot(' -----a--a---a-| ');
const e1subs = ' ^-------------! ';
const expected = '--------------(U|)';

expectObservable(e1.pipe(elementAt(100, undefined))).toBe(expected, { U: undefined });
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});
});

it('should return non-first element by zero-based index', () => {
testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
const e1 = hot(' --a--b--c--d--e--f--|');
Expand Down
24 changes: 14 additions & 10 deletions src/internal/operators/elementAt.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { ArgumentOutOfRangeError } from '../util/ArgumentOutOfRangeError';
import { Observable } from '../Observable';
import { MonoTypeOperatorFunction } from '../types';
import { MonoTypeOperatorFunction, OperatorFunction } from '../types';
import { filter } from './filter';
import { throwIfEmpty } from './throwIfEmpty';
import { defaultIfEmpty } from './defaultIfEmpty';
import { take } from './take';

export function elementAt<T, D>(index: number): MonoTypeOperatorFunction<T>;
export function elementAt<T, D>(index: number, defaultValue: D): OperatorFunction<T, T | D>;

/**
* Emits the single value at the specified `index` in a sequence of emissions
* from the source Observable.
Expand Down Expand Up @@ -52,14 +55,15 @@ import { take } from './take';
* @return {Observable} An Observable that emits a single item, if it is found.
* Otherwise, will emit the default value if given. If not, then emits an error.
*/
export function elementAt<T>(index: number, defaultValue?: T): MonoTypeOperatorFunction<T> {
if (index < 0) { throw new ArgumentOutOfRangeError(); }
export function elementAt<T, D>(index: number, defaultValue?: D): OperatorFunction<T, T | D> {
if (index < 0) {
throw new ArgumentOutOfRangeError();
}
const hasDefaultValue = arguments.length >= 2;
return (source: Observable<T>) => source.pipe(
filter((v, i) => i === index),
take(1),
hasDefaultValue
? defaultIfEmpty(defaultValue)
: throwIfEmpty(() => new ArgumentOutOfRangeError()),
);
return (source: Observable<T>) =>
source.pipe(
filter((v, i) => i === index),
take(1),
hasDefaultValue ? defaultIfEmpty(defaultValue!) : throwIfEmpty(() => new ArgumentOutOfRangeError())
);
}

0 comments on commit 5bc1b3e

Please sign in to comment.