Skip to content

Commit

Permalink
fix(operators): reorder signature of resultSelectors
Browse files Browse the repository at this point in the history
This commit swaps around the arguments of resultSelector functions
of operators that internally create an Observable<Observable<T>>,
such as switchMap, mergeMap, and concatMap.

BREAKING CHANGES:
The function signature of resultSelectors used to be (innerValue,
outerValue, innerIndex, outerIndex) but this commits changes it to
be (outerValue, innerValue, outerIndex, innerIndex), to match
signatures in RxJS 4.
  • Loading branch information
Andre Medeiros authored and benlesh committed Oct 1, 2015
1 parent b7b02d7 commit fc1724d
Show file tree
Hide file tree
Showing 15 changed files with 170 additions and 172 deletions.
108 changes: 54 additions & 54 deletions spec/operators/switchMap-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ describe('Observable.prototype.switchMap()', function () {
expect(x).toBe(expected.shift());
}, null, done);
});

it('should unsub inner observables', function(){
var unsubbed = [];

Observable.of('a', 'b').switchMap(function(x) {
return Observable.create(function(subscriber) {
subscriber.complete();
Expand All @@ -25,159 +25,159 @@ describe('Observable.prototype.switchMap()', function () {
};
});
}).subscribe();

expect(unsubbed).toEqual(['a', 'b']);
});

it('should switch inner cold observables', function (){
var x = cold( '--a--b--c--d--e--|')
var x = cold( '--a--b--c--d--e--|');
var y = cold( '---f---g---h---i--|');
var e1 = hot('---------x---------y---------|');
var expected = '-----------a--b--c----f---g---h---i--|';

var observableLookup = { x: x, y: y };

expectObservable(e1.switchMap(function(value) {
return observableLookup[value];
})).toBe(expected);
})).toBe(expected);
});

it('should switch inner hot observables', function (){
var x = hot('-----a--b--c--d--e--|')
var x = hot('-----a--b--c--d--e--|');
var y = hot('--p-o-o-p-------------f---g---h---i--|');
var e1 = hot('---------x---------y---------|');
var expected = '-----------c--d--e----f---g---h---i--|';

var observableLookup = { x: x, y: y };

expectObservable(e1.switchMap(function(value) {
return observableLookup[value];
})).toBe(expected);
})).toBe(expected);
});

it('should switch inner empty and empty', function () {
var x = Observable.empty();
var y = Observable.empty();
var e1 = hot('---------x---------y---------|');
var expected = '-----------------------------|';

var observableLookup = { x: x, y: y };

expectObservable(e1.switchMap(function(value) {
return observableLookup[value];
})).toBe(expected);
})).toBe(expected);
});

it('should switch inner empty and never', function() {
var x = Observable.empty()
var x = Observable.empty();
var y = Observable.never();
var e1 = hot('---------x---------y---------|');
var expected = '----------------------------------';

var observableLookup = { x: x, y: y };

expectObservable(e1.switchMap(function(value) {
return observableLookup[value];
})).toBe(expected);
})).toBe(expected);
});

it('should switch inner never and empty', function (){
var x = Observable.never();
var y = Observable.empty();
var e1 = hot('---------x---------y---------|');
var expected = '-----------------------------|';

var observableLookup = { x: x, y: y };

expectObservable(e1.switchMap(function(value) {
return observableLookup[value];
})).toBe(expected);
})).toBe(expected);
});

it('should switch inner never and throw', function (){
var x = Observable.never();
var y = Observable.throw(new Error('sad'));
var e1 = hot('---------x---------y---------|');
var expected = '-------------------#';

var observableLookup = { x: x, y: y };

expectObservable(e1.switchMap(function(value) {
return observableLookup[value];
})).toBe(expected, undefined, new Error('sad'));
})).toBe(expected, undefined, new Error('sad'));
});

it('should switch inner empty and throw', function (){
var x = Observable.empty();
var y = Observable.throw(new Error('sad'));
var e1 = hot('---------x---------y---------|');
var expected = '-------------------#';

var observableLookup = { x: x, y: y };

expectObservable(e1.switchMap(function(value) {
return observableLookup[value];
})).toBe(expected, undefined, new Error('sad'));
})).toBe(expected, undefined, new Error('sad'));
});

it('should handle outer empty', function (){
var e1 = Observable.empty();
var expected = '|';
expectObservable(e1.switchMap(function(value) {
return Observable.of(value);
})).toBe(expected);
});

it('should handle outer never', function (){
var e1 = Observable.never();
var expected = '----';
expectObservable(e1.switchMap(function(value) {
return Observable.of(value);
})).toBe(expected);
});

it('should handle outer throw', function (){
var e1 = Observable.throw(new Error('wah'));
var expected = '#';
expectObservable(e1.switchMap(function(value) {
return Observable.of(value);
})).toBe(expected, undefined, new Error('wah'));
});

it('should handle outer error', function (){
var x = cold( '--a--b--c--d--e--|')
var x = cold( '--a--b--c--d--e--|');
var e1 = hot('---------x---------#', undefined, new Error('boo-hoo'));
var expected = '-----------a--b--c-#';

var observableLookup = { x: x };

expectObservable(e1.switchMap(function(value) {
return observableLookup[value];
})).toBe(expected, undefined, new Error('boo-hoo'));
})).toBe(expected, undefined, new Error('boo-hoo'));
});

it('should switch with resultSelector goodness', function (){
var x = cold( '--a--b--c--d--e--|')
var x = cold( '--a--b--c--d--e--|');
var y = cold( '---f---g---h---i--|');
var e1 = hot('---------x---------y---------|');
var expected = '-----------a--b--c----f---g---h---i--|';

var observableLookup = { x: x, y: y };

var expectedValues = {
a: ['a', 'x', 0, 0],
b: ['b', 'x', 1, 0],
c: ['c', 'x', 2, 0],
f: ['f', 'y', 0, 1],
g: ['g', 'y', 1, 1],
h: ['h', 'y', 2, 1],
i: ['i', 'y', 3, 1]
a: ['x', 'a', 0, 0],
b: ['x', 'b', 0, 1],
c: ['x', 'c', 0, 2],
f: ['y', 'f', 1, 0],
g: ['y', 'g', 1, 1],
h: ['y', 'h', 1, 2],
i: ['y', 'i', 1, 3]
};

expectObservable(e1.switchMap(function(value) {
return observableLookup[value];
}, function(innerValue, outerValue, innerIndex, outerIndex) {
return [innerValue, outerValue, innerIndex, outerIndex];
})).toBe(expected, expectedValues);
})).toBe(expected, expectedValues);
});
});
10 changes: 5 additions & 5 deletions src/InnerSubscriber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ import { errorObject } from './util/errorObject';

export default class InnerSubscriber<T, R> extends Subscriber<R> {
index: number = 0;

constructor(private parent: OuterSubscriber<T, R>, private outerValue: T, private outerIndex: number) {
super();
}

_next(value: R) {
const index = this.index++;
this.parent.notifyNext(value, this.outerValue, index, this.outerIndex);
this.parent.notifyNext(this.outerValue, value, this.outerIndex, index);
}

_error(error: any) {
this.parent.notifyError(error, this);
}

_complete() {
this.parent.notifyComplete(this);
}
Expand Down
6 changes: 3 additions & 3 deletions src/OuterSubscriber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ export default class OuterSubscriber<T, R> extends Subscriber<T> {
notifyComplete(inner?: InnerSubscriber<T, R>) {
this.destination.complete();
}
notifyNext(innerValue: R, outerValue: T, innerIndex: number, outerIndex: number) {

notifyNext(outerValue: T, innerValue: R, outerIndex: number, innerIndex: number) {
this.destination.next(innerValue);
}

notifyError(error?: any, inner?: InnerSubscriber<T, R>) {
this.destination.error(error);
}
Expand Down
14 changes: 7 additions & 7 deletions src/operators/combineLatest-support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class CombineLatestSubscriber<T, R> extends OuterSubscriber<T, R> {
private values: any[] = [];
private observables: any[] = [];
private toRespond: number[] = [];

constructor(destination: Subscriber<R>, private project?: (...values: Array<any>) => R) {
super(destination);
}
Expand All @@ -39,7 +39,7 @@ export class CombineLatestSubscriber<T, R> extends OuterSubscriber<T, R> {
toRespond.push(toRespond.length);
this.observables.push(observable);
}

_complete() {
const observables = this.observables;
const len = observables.length;
Expand All @@ -59,23 +59,23 @@ export class CombineLatestSubscriber<T, R> extends OuterSubscriber<T, R> {
this.destination.complete();
}
}
notifyNext(value: R, observable: any, innerIndex: number, outerIndex: number) {

notifyNext(observable: any, value: R, outerIndex: number, innerIndex: number) {
const values = this.values;
values[outerIndex] = value;
const toRespond = this.toRespond;

if(toRespond.length > 0) {
const found = toRespond.indexOf(outerIndex);
if(found !== -1) {
toRespond.splice(found, 1);
}
}

if(toRespond.length === 0) {
const project = this.project;
const destination = this.destination;

if(project) {
let result = tryCatch(project).apply(this, values);
if(result === errorObject) {
Expand Down
2 changes: 1 addition & 1 deletion src/operators/concatMapTo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import Observable from '../Observable';
import { MergeMapToOperator } from './mergeMapTo-support';

export default function concatMapTo<T, R, R2>(observable: Observable<R>,
projectResult?: (innerValue: R, outerValue: T, innerIndex: number, outerIndex: number) => R2) : Observable<R2> {
projectResult?: (outerValue: T, innerValue: R, outerIndex: number, innerIndex: number) => R2) : Observable<R2> {
return this.lift(new MergeMapToOperator(observable, projectResult, 1));
}
16 changes: 8 additions & 8 deletions src/operators/expand-support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import OuterSubscriber from '../OuterSubscriber';
import subscribeToResult from '../util/subscribeToResult';

export class ExpandOperator<T, R> implements Operator<T, R> {
constructor(private project: (value: T, index: number) => Observable<any>,
constructor(private project: (value: T, index: number) => Observable<any>,
private concurrent: number = Number.POSITIVE_INFINITY) {
}

Expand All @@ -27,15 +27,15 @@ export class ExpandSubscriber<T, R> extends OuterSubscriber<T, R> {
private active: number = 0;
private hasCompleted: boolean = false;
private buffer: any[];
constructor(destination: Observer<T>, private project: (value: T, index: number) => Observable<R>,

constructor(destination: Observer<T>, private project: (value: T, index: number) => Observable<R>,
private concurrent: number = Number.POSITIVE_INFINITY) {
super(destination);
if(concurrent < Number.POSITIVE_INFINITY) {
this.buffer = [];
}
}

_next(value: any) {
const index = this.index++;
this.destination.next(value);
Expand All @@ -55,14 +55,14 @@ export class ExpandSubscriber<T, R> extends OuterSubscriber<T, R> {
this.buffer.push(value);
}
}

_complete() {
this.hasCompleted = true;
if(this.hasCompleted && this.active === 0) {
this.destination.complete();
}
}

notifyComplete(innerSub: Subscription<T>) {
const buffer = this.buffer;
this.remove(innerSub);
Expand All @@ -74,8 +74,8 @@ export class ExpandSubscriber<T, R> extends OuterSubscriber<T, R> {
this.destination.complete();
}
}
notifyNext(innerValue: R, outerValue: T, innerIndex: number, outerIndex: number) {

notifyNext(outerValue: T, innerValue: R, outerIndex: number, innerIndex: number) {
this._next(innerValue);
}
}
Loading

0 comments on commit fc1724d

Please sign in to comment.