1 import { Operator } from '../Operator';
2 import { Observable } from '../Observable';
3 import { Subscriber } from '../Subscriber';
4 import { OperatorFunction, MonoTypeOperatorFunction } from '../types';
6 /* tslint:disable:max-line-length */
7 export function defaultIfEmpty<T>(defaultValue?: T): MonoTypeOperatorFunction<T>;
8 export function defaultIfEmpty<T, R>(defaultValue?: R): OperatorFunction<T, T | R>;
9 /* tslint:enable:max-line-length */
12 * Emits a given value if the source Observable completes without emitting any
13 * `next` value, otherwise mirrors the source Observable.
15 * <span class="informal">If the source Observable turns out to be empty, then
16 * this operator will emit a default value.</span>
18 * ![](defaultIfEmpty.png)
20 * `defaultIfEmpty` emits the values emitted by the source Observable or a
21 * specified default value if the source Observable is empty (completes without
22 * having emitted any `next` value).
25 * If no clicks happen in 5 seconds, then emit "no clicks"
27 * import { fromEvent } from 'rxjs';
28 * import { defaultIfEmpty, takeUntil } from 'rxjs/operators';
30 * const clicks = fromEvent(document, 'click');
31 * const clicksBeforeFive = clicks.pipe(takeUntil(interval(5000)));
32 * const result = clicksBeforeFive.pipe(defaultIfEmpty('no clicks'));
33 * result.subscribe(x => console.log(x));
39 * @param {any} [defaultValue=null] The default value used if the source
40 * Observable is empty.
41 * @return {Observable} An Observable that emits either the specified
42 * `defaultValue` if the source Observable emits no items, or the values emitted
43 * by the source Observable.
44 * @method defaultIfEmpty
47 export function defaultIfEmpty<T, R>(defaultValue: R = null): OperatorFunction<T, T | R> {
48 return (source: Observable<T>) => source.lift(new DefaultIfEmptyOperator(defaultValue)) as Observable<T | R>;
51 class DefaultIfEmptyOperator<T, R> implements Operator<T, T | R> {
53 constructor(private defaultValue: R) {
56 call(subscriber: Subscriber<T | R>, source: any): any {
57 return source.subscribe(new DefaultIfEmptySubscriber(subscriber, this.defaultValue));
62 * We need this JSDoc comment for affecting ESDoc.
66 class DefaultIfEmptySubscriber<T, R> extends Subscriber<T> {
67 private isEmpty: boolean = true;
69 constructor(destination: Subscriber<T | R>, private defaultValue: R) {
73 protected _next(value: T): void {
75 this.destination.next(value);
78 protected _complete(): void {
80 this.destination.next(this.defaultValue);
82 this.destination.complete();