Skip to content

Commit

Permalink
feat(operators): add mapResponse ngrx#4230
Browse files Browse the repository at this point in the history
  • Loading branch information
tom9744 committed May 11, 2024
1 parent 51034e6 commit 9693f1f
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 0 deletions.
79 changes: 79 additions & 0 deletions modules/operators/spec/map-response.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { noop, Observable, of, throwError } from 'rxjs';
import { mapResponse } from '..';
import { concatMap, finalize } from 'rxjs/operators';

describe('mapResponse', () => {
it('should invoke next callback on next', () => {
const nextCallback = jest.fn<void, [number]>();

of(1, 2, 3)
.pipe(
mapResponse({
next: nextCallback,
error: noop,
})
)
.subscribe();

expect(nextCallback.mock.calls).toEqual([[1], [2], [3]]);
});

it('should invoke error callback on error', () => {
const errorCallback = jest.fn<void, [{ message: string }]>();
const error = { message: 'error' };

throwError(() => error)
.pipe(
mapResponse({
next: noop,
error: errorCallback,
})
)
.subscribe();

expect(errorCallback).toHaveBeenCalledWith(error);
});

it('should invoke error callback on the exception thrown in next', () => {
const errorCallback = jest.fn<void, [{ message: string }]>();
const error = { message: 'error' };

function producesError() {
throw error;
}

of(1)
.pipe(
mapResponse({
next: producesError,
error: errorCallback,
})
)
.subscribe();

expect(errorCallback).toHaveBeenCalledWith(error);
});

it('should not unsubscribe from outer observable on inner observable error', () => {
const innerCompleteCallback = jest.fn<void, []>();
const outerCompleteCallback = jest.fn<void, []>();

new Observable((subscriber) => subscriber.next(1))
.pipe(
concatMap(() =>
throwError(() => 'error').pipe(
mapResponse({
next: noop,
error: noop,
}),
finalize(innerCompleteCallback)
)
),
finalize(outerCompleteCallback)
)
.subscribe();

expect(innerCompleteCallback).toHaveBeenCalled();
expect(outerCompleteCallback).not.toHaveBeenCalled();
});
});
1 change: 1 addition & 0 deletions modules/operators/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { concatLatestFrom } from './concat_latest_from';
export { mapResponse } from './map-response';
export { tapResponse } from './tap-response';
17 changes: 17 additions & 0 deletions modules/operators/src/map-response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Observable, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';

export function mapResponse<T, E, R1, R2>(observerOrNext: {
next: (value: T) => R1;
error: (error: E) => R2;
}): (source$: Observable<T>) => Observable<R1 | R2> {
return (source$) =>
source$.pipe(
map((value) => {
return observerOrNext.next(value);
}),
catchError((error) => {
return of(observerOrNext.error(error));
})
);
}

0 comments on commit 9693f1f

Please sign in to comment.