From b5948f97ea51caadd8d298a97d7b903f8c05c0df Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Thu, 13 Jul 2017 15:41:54 -0700 Subject: [PATCH] feat(dematerialize): add higher-ordeer lettable version of dematerialize --- src/operator/dematerialize.ts | 29 ++------------ src/operators/dematerialize.ts | 72 ++++++++++++++++++++++++++++++++++ src/operators/index.ts | 1 + 3 files changed, 77 insertions(+), 25 deletions(-) create mode 100644 src/operators/dematerialize.ts diff --git a/src/operator/dematerialize.ts b/src/operator/dematerialize.ts index ceccab40c4..f8eeecaaab 100644 --- a/src/operator/dematerialize.ts +++ b/src/operator/dematerialize.ts @@ -1,7 +1,7 @@ -import { Operator } from '../Operator'; + import { Observable } from '../Observable'; -import { Subscriber } from '../Subscriber'; import { Notification } from '../Notification'; +import { dematerialize as higherOrder } from '../operators'; /** * Converts an Observable of {@link Notification} objects into the emissions @@ -43,27 +43,6 @@ import { Notification } from '../Notification'; * @method dematerialize * @owner Observable */ -export function dematerialize(this: Observable): Observable { - return this.lift(new DeMaterializeOperator()); -} - -class DeMaterializeOperator, R> implements Operator { - call(subscriber: Subscriber, source: any): any { - return source.subscribe(new DeMaterializeSubscriber(subscriber)); - } -} - -/** - * We need this JSDoc comment for affecting ESDoc. - * @ignore - * @extends {Ignored} - */ -class DeMaterializeSubscriber> extends Subscriber { - constructor(destination: Subscriber) { - super(destination); - } - - protected _next(value: T) { - value.observe(this.destination); - } +export function dematerialize(this: Observable>): Observable { + return higherOrder()(this); } diff --git a/src/operators/dematerialize.ts b/src/operators/dematerialize.ts new file mode 100644 index 0000000000..3422c7f518 --- /dev/null +++ b/src/operators/dematerialize.ts @@ -0,0 +1,72 @@ +import { Operator } from '../Operator'; +import { Observable } from '../Observable'; +import { Subscriber } from '../Subscriber'; +import { Notification } from '../Notification'; +import { OperatorFunction } from '../interfaces'; + +/** + * Converts an Observable of {@link Notification} objects into the emissions + * that they represent. + * + * Unwraps {@link Notification} objects as actual `next`, + * `error` and `complete` emissions. The opposite of {@link materialize}. + * + * + * + * `dematerialize` is assumed to operate an Observable that only emits + * {@link Notification} objects as `next` emissions, and does not emit any + * `error`. Such Observable is the output of a `materialize` operation. Those + * notifications are then unwrapped using the metadata they contain, and emitted + * as `next`, `error`, and `complete` on the output Observable. + * + * Use this operator in conjunction with {@link materialize}. + * + * @example Convert an Observable of Notifications to an actual Observable + * var notifA = new Rx.Notification('N', 'A'); + * var notifB = new Rx.Notification('N', 'B'); + * var notifE = new Rx.Notification('E', void 0, + * new TypeError('x.toUpperCase is not a function') + * ); + * var materialized = Rx.Observable.of(notifA, notifB, notifE); + * var upperCase = materialized.dematerialize(); + * upperCase.subscribe(x => console.log(x), e => console.error(e)); + * + * // Results in: + * // A + * // B + * // TypeError: x.toUpperCase is not a function + * + * @see {@link Notification} + * @see {@link materialize} + * + * @return {Observable} An Observable that emits items and notifications + * embedded in Notification objects emitted by the source Observable. + * @method dematerialize + * @owner Observable + */ +export function dematerialize(): OperatorFunction, T> { + return function dematerializeOperatorFunction(source: Observable>) { + return source.lift(new DeMaterializeOperator()); + }; +} + +class DeMaterializeOperator, R> implements Operator { + call(subscriber: Subscriber, source: any): any { + return source.subscribe(new DeMaterializeSubscriber(subscriber)); + } +} + +/** + * We need this JSDoc comment for affecting ESDoc. + * @ignore + * @extends {Ignored} + */ +class DeMaterializeSubscriber> extends Subscriber { + constructor(destination: Subscriber) { + super(destination); + } + + protected _next(value: T) { + value.observe(this.destination); + } +} diff --git a/src/operators/index.ts b/src/operators/index.ts index 07388d0841..d9b911f5cb 100644 --- a/src/operators/index.ts +++ b/src/operators/index.ts @@ -5,6 +5,7 @@ export { concat } from './concat'; export { concatAll } from './concatAll'; export { concatMap } from './concatMap'; export { defaultIfEmpty } from './defaultIfEmpty'; +export { dematerialize } from './dematerialize'; export { filter } from './filter'; export { ignoreElements } from './ignoreElements'; export { map } from './map';