Skip to content

Commit 639236e

Browse files
committed
feat(throwError): functional version of throwError
- eliminates `ErrorObservable` - eliminates `_throw` - updates tests BREAKING CHANGE: Observable.throw no longer available in TypeScript without a cast
1 parent d487d6b commit 639236e

File tree

9 files changed

+74
-116
lines changed

9 files changed

+74
-116
lines changed

spec/exports-spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { onErrorResumeNext } from '../src/internal/observable/onErrorResumeNext'
1919
import { pairs } from '../src/internal/observable/pairs';
2020
import { race } from '../src/internal/observable/race';
2121
import { range } from '../src/internal/observable/range';
22-
import { _throw } from '../src/internal/observable/throw';
22+
import { throwError } from '../src/internal/observable/throwError';
2323
import { timer } from '../src/internal/observable/timer';
2424
import { using } from '../src/internal/observable/using';
2525
import { zip } from '../src/internal/observable/zip';
@@ -106,8 +106,8 @@ describe('exports', () => {
106106
expect(range).to.equal(Rx.Observable.range);
107107
});
108108

109-
it('should have rxjs/observable/throw', () => {
110-
expect(_throw).to.equal(Rx.Observable.throw);
109+
it('should have rxjs/observable/throwError', () => {
110+
expect(throwError).to.equal(Rx.Observable.throw);
111111
});
112112

113113
it('should have rxjs/observable/timer', () => {

spec/observables/throw-spec.ts renamed to spec/observables/throwError-spec.ts

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
import { expect } from 'chai';
22
import * as Rx from '../../src/Rx';
3-
import { ErrorObservable } from '../../src/internal/observable/ErrorObservable';
3+
import { throwError } from '../../src/create';
44
import marbleTestingSignature = require('../helpers/marble-testing'); // tslint:disable-line:no-require-imports
55

6-
declare const { asDiagram };
6+
declare const asDiagram: any;
77
declare const expectObservable: typeof marbleTestingSignature.expectObservable;
88
declare const rxTestScheduler: Rx.TestScheduler;
9-
const Observable = Rx.Observable;
109

1110
/** @test {throw} */
12-
describe('Observable.throw', () => {
11+
describe('throwError', () => {
1312
asDiagram('throw(e)')('should create a cold observable that just emits an error', () => {
1413
const expected = '#';
15-
const e1 = Observable.throw('error');
14+
const e1 = throwError('error');
1615
expectObservable(e1).toBe(expected);
1716
});
1817

1918
it('should emit one value', (done: MochaDone) => {
2019
let calls = 0;
21-
Observable.throw('bad').subscribe(() => {
20+
throwError('bad').subscribe(() => {
2221
done(new Error('should not be called'));
2322
}, (err: any) => {
2423
expect(++calls).to.equal(1);
@@ -27,21 +26,8 @@ describe('Observable.throw', () => {
2726
});
2827
});
2928

30-
it('should create expose a error property', () => {
31-
const e = Observable.throw('error');
32-
33-
expect(e['error']).to.equal('error');
34-
});
35-
36-
it('should create ErrorObservable via static create function', () => {
37-
const e = new ErrorObservable('error');
38-
const r = ErrorObservable.create('error');
39-
40-
expect(e).to.deep.equal(r);
41-
});
42-
4329
it('should accept scheduler', () => {
44-
const e = Observable.throw('error', rxTestScheduler);
30+
const e = throwError('error', rxTestScheduler);
4531

4632
expectObservable(e).toBe('#');
4733
});

src/add/observable/throw.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import { Observable } from '../../internal/Observable';
2-
import { _throw } from '../../internal/observable/throw';
2+
import { throwError } from '../../internal/observable/throwError';
33

4-
Observable.throw = _throw;
4+
(Observable as any).throw = throwError;

src/create/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export { onErrorResumeNext } from '../internal/observable/onErrorResumeNext';
1919
export { pairs } from '../internal/observable/pairs';
2020
export { race } from '../internal/observable/race';
2121
export { range } from '../internal/observable/range';
22-
export { _throw as throwError } from '../internal/observable/throw';
22+
export { throwError } from '../internal/observable/throwError';
2323
export { timer } from '../internal/observable/timer';
2424
export { using } from '../internal/observable/using';
2525
export { zip } from '../internal/observable/zip';

src/internal/Notification.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { PartialObserver } from './Observer';
22
import { Observable } from './Observable';
33
import { empty } from './observable/empty';
44
import { of } from './observable/of';
5-
import { _throw } from './observable/throw';
5+
import { throwError } from './observable/throwError';
66

77
/**
88
* Represents a push-based event or value that an {@link Observable} can emit.
@@ -89,7 +89,7 @@ export class Notification<T> {
8989
case 'N':
9090
return of(this.value);
9191
case 'E':
92-
return _throw(this.error);
92+
return throwError(this.error);
9393
case 'C':
9494
return empty();
9595
}

src/internal/Observable.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { Subscription, AnonymousSubscription, TeardownLogic } from './Subscripti
55
import { root } from './util/root';
66
import { toSubscriber } from './util/toSubscriber';
77
import { IfObservable } from './observable/IfObservable';
8-
import { ErrorObservable } from './observable/ErrorObservable';
98
import { observable as Symbol_observable } from '../internal/symbol/observable';
109
import { OperatorFunction } from '../internal/types';
1110
import { pipeFromArray } from './util/pipe';
@@ -256,7 +255,6 @@ export class Observable<T> implements Subscribable<T> {
256255

257256
// `if` and `throw` are special snow flakes, the compiler sees them as reserved words
258257
static if: typeof IfObservable.create;
259-
static throw: typeof ErrorObservable.create;
260258

261259
/**
262260
* An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable

src/internal/observable/ErrorObservable.ts

Lines changed: 0 additions & 83 deletions
This file was deleted.

src/internal/observable/throw.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/internal/observable/throwError.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { Observable } from '../Observable';
2+
import { IScheduler } from '../Scheduler';
3+
import { Subscriber } from '../Subscriber';
4+
5+
/**
6+
* Creates an Observable that emits no items to the Observer and immediately
7+
* emits an error notification.
8+
*
9+
* <span class="informal">Just emits 'error', and nothing else.
10+
* </span>
11+
*
12+
* <img src="./img/throw.png" width="100%">
13+
*
14+
* This static operator is useful for creating a simple Observable that only
15+
* emits the error notification. It can be used for composing with other
16+
* Observables, such as in a {@link mergeMap}.
17+
*
18+
* @example <caption>Emit the number 7, then emit an error.</caption>
19+
* var result = Rx.Observable.throw(new Error('oops!')).startWith(7);
20+
* result.subscribe(x => console.log(x), e => console.error(e));
21+
*
22+
* @example <caption>Map and flatten numbers to the sequence 'a', 'b', 'c', but throw an error for 13</caption>
23+
* var interval = Rx.Observable.interval(1000);
24+
* var result = interval.mergeMap(x =>
25+
* x === 13 ?
26+
* Rx.Observable.throw('Thirteens are bad') :
27+
* Rx.Observable.of('a', 'b', 'c')
28+
* );
29+
* result.subscribe(x => console.log(x), e => console.error(e));
30+
*
31+
* @see {@link create}
32+
* @see {@link empty}
33+
* @see {@link never}
34+
* @see {@link of}
35+
*
36+
* @param {any} error The particular Error to pass to the error notification.
37+
* @param {Scheduler} [scheduler] A {@link IScheduler} to use for scheduling
38+
* the emission of the error notification.
39+
* @return {Observable} An error Observable: emits only the error notification
40+
* using the given error argument.
41+
* @static true
42+
* @name throw
43+
* @owner Observable
44+
*/
45+
export function throwError(error: any, scheduler?: IScheduler): Observable<never> {
46+
if (!scheduler) {
47+
return new Observable(subscriber => subscriber.error(error));
48+
} else {
49+
return new Observable(subscriber => scheduler.schedule(dispatch, 0, { error, subscriber }));
50+
}
51+
}
52+
53+
interface DispatchArg {
54+
error: any;
55+
subscriber: Subscriber<any>;
56+
}
57+
58+
function dispatch({ error, subscriber }: DispatchArg) {
59+
subscriber.error(error);
60+
}

0 commit comments

Comments
 (0)