source: trip-planner-front/node_modules/rxjs/src/internal/operators/single.ts@ 8d391a1

Last change on this file since 8d391a1 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 3.8 KB
Line 
1import { Observable } from '../Observable';
2import { Operator } from '../Operator';
3import { Subscriber } from '../Subscriber';
4import { EmptyError } from '../util/EmptyError';
5
6import { Observer, MonoTypeOperatorFunction, TeardownLogic } from '../types';
7
8/**
9 * Returns an Observable that emits the single item emitted by the source Observable that matches a specified
10 * predicate, if that Observable emits one such item. If the source Observable emits more than one such item or no
11 * items, notify of an IllegalArgumentException or NoSuchElementException respectively. If the source Observable
12 * emits items but none match the specified predicate then `undefined` is emitted.
13 *
14 * <span class="informal">Like {@link first}, but emit with error notification if there is more than one value.</span>
15 * ![](single.png)
16 *
17 * ## Example
18 * emits 'error'
19 * ```ts
20 * import { range } from 'rxjs';
21 * import { single } from 'rxjs/operators';
22 *
23 * const numbers = range(1,5).pipe(single());
24 * numbers.subscribe(x => console.log('never get called'), e => console.log('error'));
25 * // result
26 * // 'error'
27 * ```
28 *
29 * emits 'undefined'
30 * ```ts
31 * import { range } from 'rxjs';
32 * import { single } from 'rxjs/operators';
33 *
34 * const numbers = range(1,5).pipe(single(x => x === 10));
35 * numbers.subscribe(x => console.log(x));
36 * // result
37 * // 'undefined'
38 * ```
39 *
40 * @see {@link first}
41 * @see {@link find}
42 * @see {@link findIndex}
43 * @see {@link elementAt}
44 *
45 * @throws {EmptyError} Delivers an EmptyError to the Observer's `error`
46 * callback if the Observable completes before any `next` notification was sent.
47 * @param {Function} predicate - A predicate function to evaluate items emitted by the source Observable.
48 * @return {Observable<T>} An Observable that emits the single item emitted by the source Observable that matches
49 * the predicate or `undefined` when no items match.
50 *
51 * @method single
52 * @owner Observable
53 */
54export function single<T>(predicate?: (value: T, index: number, source: Observable<T>) => boolean): MonoTypeOperatorFunction<T> {
55 return (source: Observable<T>) => source.lift(new SingleOperator(predicate, source));
56}
57
58class SingleOperator<T> implements Operator<T, T> {
59 constructor(private predicate?: (value: T, index: number, source: Observable<T>) => boolean,
60 private source?: Observable<T>) {
61 }
62
63 call(subscriber: Subscriber<T>, source: any): TeardownLogic {
64 return source.subscribe(new SingleSubscriber(subscriber, this.predicate, this.source));
65 }
66}
67
68/**
69 * We need this JSDoc comment for affecting ESDoc.
70 * @ignore
71 * @extends {Ignored}
72 */
73class SingleSubscriber<T> extends Subscriber<T> {
74 private seenValue: boolean = false;
75 private singleValue: T;
76 private index: number = 0;
77
78 constructor(destination: Observer<T>,
79 private predicate?: (value: T, index: number, source: Observable<T>) => boolean,
80 private source?: Observable<T>) {
81 super(destination);
82 }
83
84 private applySingleValue(value: T): void {
85 if (this.seenValue) {
86 this.destination.error('Sequence contains more than one element');
87 } else {
88 this.seenValue = true;
89 this.singleValue = value;
90 }
91 }
92
93 protected _next(value: T): void {
94 const index = this.index++;
95
96 if (this.predicate) {
97 this.tryNext(value, index);
98 } else {
99 this.applySingleValue(value);
100 }
101 }
102
103 private tryNext(value: T, index: number): void {
104 try {
105 if (this.predicate(value, index, this.source)) {
106 this.applySingleValue(value);
107 }
108 } catch (err) {
109 this.destination.error(err);
110 }
111 }
112
113 protected _complete(): void {
114 const destination = this.destination;
115
116 if (this.index > 0) {
117 destination.next(this.seenValue ? this.singleValue : undefined);
118 destination.complete();
119 } else {
120 destination.error(new EmptyError);
121 }
122 }
123}
Note: See TracBrowser for help on using the repository browser.