Skip to content

Commit

Permalink
feat(switchMap): removed deprecated switchMap(project, resultSelector…
Browse files Browse the repository at this point in the history
…) call pattern

BREAKING CHANGE: `switchMap(project, resultSelector)` call pattern is no longer available. [Read more](https://rxjs.dev/deprecations/resultSelector).
  • Loading branch information
demensky committed Oct 30, 2022
1 parent 2c6da12 commit ff3a705
Show file tree
Hide file tree
Showing 5 changed files with 12 additions and 113 deletions.
2 changes: 0 additions & 2 deletions api_guard/dist/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -672,8 +672,6 @@ export interface SubscriptionLike extends Unsubscribable {
export declare function switchAll<O extends ObservableInput<any>>(): OperatorFunction<O, ObservedValueOf<O>>;

export declare function switchMap<T, O extends ObservableInput<any>>(project: (value: T, index: number) => O): OperatorFunction<T, ObservedValueOf<O>>;
export declare function switchMap<T, O extends ObservableInput<any>>(project: (value: T, index: number) => O, resultSelector: undefined): OperatorFunction<T, ObservedValueOf<O>>;
export declare function switchMap<T, R, O extends ObservableInput<any>>(project: (value: T, index: number) => O, resultSelector: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R): OperatorFunction<T, R>;

export declare function switchMapTo<O extends ObservableInput<unknown>>(innerObservable: O): OperatorFunction<unknown, ObservedValueOf<O>>;

Expand Down
2 changes: 0 additions & 2 deletions api_guard/dist/types/operators/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,6 @@ export declare function subscribeOn<T>(scheduler: SchedulerLike, delay?: number)
export declare function switchAll<O extends ObservableInput<any>>(): OperatorFunction<O, ObservedValueOf<O>>;

export declare function switchMap<T, O extends ObservableInput<any>>(project: (value: T, index: number) => O): OperatorFunction<T, ObservedValueOf<O>>;
export declare function switchMap<T, O extends ObservableInput<any>>(project: (value: T, index: number) => O, resultSelector: undefined): OperatorFunction<T, ObservedValueOf<O>>;
export declare function switchMap<T, R, O extends ObservableInput<any>>(project: (value: T, index: number) => O, resultSelector: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R): OperatorFunction<T, R>;

export declare function switchMapTo<O extends ObservableInput<unknown>>(innerObservable: O): OperatorFunction<unknown, ObservedValueOf<O>>;

Expand Down
20 changes: 0 additions & 20 deletions spec-dtslint/operators/switchMap-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,6 @@ it('should support a projector that takes an index', () => {
const o = of(1, 2, 3).pipe(switchMap(p => of(Boolean(p)))); // $ExpectType Observable<boolean>
});

it('should infer correctly by using the resultSelector first parameter', () => {
const o = of(1, 2, 3).pipe(switchMap(p => of(Boolean(p)), a => a)); // $ExpectType Observable<number>
});

it('should infer correctly by using the resultSelector second parameter', () => {
const o = of(1, 2, 3).pipe(switchMap(p => of(Boolean(p)), (a, b) => b)); // $ExpectType Observable<boolean>
});

it('should support a resultSelector that takes an inner index', () => {
const o = of(1, 2, 3).pipe(switchMap(p => of(Boolean(p)), (a, b, i) => a)); // $ExpectType Observable<number>
});

it('should support a resultSelector that takes an inner and outer index', () => {
const o = of(1, 2, 3).pipe(switchMap(p => of(Boolean(p)), (a, b, i, ii) => a)); // $ExpectType Observable<number>
});

it('should support an undefined resultSelector', () => {
const o = of(1, 2, 3).pipe(switchMap(p => of(Boolean(p)), undefined)); // $ExpectType Observable<boolean>
});

it('should support union-type projections with empty streams', () => {
const o = of(1, 2, 3).pipe(switchMap(n => Math.random() < 0.5 ? of(123) : of())); // $ExpectType Observable<number>
});
Expand Down
51 changes: 0 additions & 51 deletions spec/operators/switchMap-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,57 +30,6 @@ describe('switchMap', () => {
});
});

it('should support the deprecated resultSelector', () => {
const results: Array<number[]> = [];

of(1, 2, 3)
.pipe(
switchMap(
(x) => of(x, x + 1, x + 2),
(a, b, i, ii) => [a, b, i, ii]
)
)
.subscribe({
next(value) {
results.push(value);
},
error(err) {
throw err;
},
complete() {
expect(results).to.deep.equal([
[1, 1, 0, 0],
[1, 2, 0, 1],
[1, 3, 0, 2],
[2, 2, 1, 0],
[2, 3, 1, 1],
[2, 4, 1, 2],
[3, 3, 2, 0],
[3, 4, 2, 1],
[3, 5, 2, 2],
]);
},
});
});

it('should support a void resultSelector (still deprecated)', () => {
const results: number[] = [];

of(1, 2, 3)
.pipe(switchMap((x) => of(x, x + 1, x + 2), void 0))
.subscribe({
next(value) {
results.push(value);
},
error(err) {
throw err;
},
complete() {
expect(results).to.deep.equal([1, 2, 3, 2, 3, 4, 3, 4, 5]);
},
});
});

it('should unsub inner observables', () => {
const unsubbed: string[] = [];

Expand Down
50 changes: 12 additions & 38 deletions src/internal/operators/switchMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,6 @@ import { innerFrom } from '../observable/innerFrom';
import { operate } from '../util/lift';
import { createOperatorSubscriber } from './OperatorSubscriber';

/* tslint:disable:max-line-length */
export function switchMap<T, O extends ObservableInput<any>>(
project: (value: T, index: number) => O
): OperatorFunction<T, ObservedValueOf<O>>;
/** @deprecated The `resultSelector` parameter will be removed in v8. Use an inner `map` instead. Details: https://rxjs.dev/deprecations/resultSelector */
export function switchMap<T, O extends ObservableInput<any>>(
project: (value: T, index: number) => O,
resultSelector: undefined
): OperatorFunction<T, ObservedValueOf<O>>;
/** @deprecated The `resultSelector` parameter will be removed in v8. Use an inner `map` instead. Details: https://rxjs.dev/deprecations/resultSelector */
export function switchMap<T, R, O extends ObservableInput<any>>(
project: (value: T, index: number) => O,
resultSelector: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R
): OperatorFunction<T, R>;
/* tslint:enable:max-line-length */

/**
* Projects each source value to an Observable which is merged in the output
* Observable, emitting values only from the most recently projected Observable.
Expand Down Expand Up @@ -79,14 +63,12 @@ export function switchMap<T, R, O extends ObservableInput<any>>(
* that, when applied to an item emitted by the source Observable, returns an
* Observable.
* @return A function that returns an Observable that emits the result of
* applying the projection function (and the optional deprecated
* `resultSelector`) to each item emitted by the source Observable and taking
* only the values from the most recently projected inner Observable.
* applying the projection function to each item emitted by the source Observable
* and taking only the values from the most recently projected inner Observable.
*/
export function switchMap<T, R, O extends ObservableInput<any>>(
project: (value: T, index: number) => O,
resultSelector?: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R
): OperatorFunction<T, ObservedValueOf<O> | R> {
export function switchMap<T, O extends ObservableInput<any>>(
project: (value: T, index: number) => O
): OperatorFunction<T, ObservedValueOf<O>> {
return operate((source, subscriber) => {
let innerSubscriber: Subscriber<ObservedValueOf<O>> | null = null;
let index = 0;
Expand All @@ -103,24 +85,16 @@ export function switchMap<T, R, O extends ObservableInput<any>>(
(value) => {
// Cancel the previous inner subscription if there was one
innerSubscriber?.unsubscribe();
let innerIndex = 0;
const outerIndex = index++;
// Start the next inner subscription
innerFrom(project(value, outerIndex)).subscribe(
(innerSubscriber = createOperatorSubscriber(
subscriber,
// When we get a new inner value, next it through. Note that this is
// handling the deprecate result selector here. This is because with this architecture
// it ends up being smaller than using the map operator.
(innerValue) => subscriber.next(resultSelector ? resultSelector(value, innerValue, outerIndex, innerIndex++) : innerValue),
() => {
// The inner has completed. Null out the inner subscriber to
// free up memory and to signal that we have no inner subscription
// currently.
innerSubscriber = null!;
checkComplete();
}
))
(innerSubscriber = createOperatorSubscriber(subscriber, undefined, () => {
// The inner has completed. Null out the inner subscriber to
// free up memory and to signal that we have no inner subscription
// currently.
innerSubscriber = null!;
checkComplete();
}))
);
},
() => {
Expand Down

0 comments on commit ff3a705

Please sign in to comment.