Do you want to request a feature or report a bug?
Request a feature
What is the current behavior?
Mapping observable notifications to actions can be verbose. Many effects that handle network effects often need map, catchError, and Observable.of to correctly map observable notifications to actions:
someNetworkRequest$
.pipe(
map(response => createSuccessAction(response)),
catchError(error => Observable.of(createFailureAction(error))),
);
For some effects (like those managing a WebSocket connection) they may also want to map the completion notification:
webSocketConnection$
.pipe(
map(message => createMessageAction(message)),
catchError(error => Observable.of(createFailureAction(error))),
concat(Observable.of(createCompletionAction())),
);
What is the expected behavior?
Recommend adding a mapToAction helper operator that enables developers to more conveniently map observable notifications to actions:
webSocketConnection$
.pipe(
mapToAction(
message => createMessageAction(action),
error => createFailureAction(error),
complete => createCompletionAction(),
),
);
mapToAction would work similarly to observable$.subscribe() and tap where you can provide it optional functions for next, error, and complete or a partial observer.
If it gets approved here I will make the change to both redux-observable and ngrx/effects.
Which versions of redux-observable, and which browser and OS are affected by this issue? Did this work in previous versions of redux-observable?
All versions.
For some effects (like those managing a WebSocket connection) they may also want to map the completion notification:
Does that example work? I never tried that before but does concat of a "complete" action work as only being fired for completion versus after the map?
@wldcordeiro in v6 there is no concat pipeable operator anymore so _that code_ as-is doesn't work but the static factory function usage does:
import { concat, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
concat(
webSocketConnection$.pipe(
map(message => createMessageAction(message)),
catchError(error => Observable.of(createFailureAction(error)))
),
of(createCompletionAction())
)
6.2 now has a endWith operator that makes this easier as well:
import { of } from 'rxjs';
import { map, catchError, endWith } from 'rxjs/operators';
webSocketConnection$.pipe(
map(message => createMessageAction(message)),
catchError(error => Observable.of(createFailureAction(error))),
endWith(createCompletionAction())
)
@jayphelps that was actually what confused me, the fact that the pipeable was gone from my testing made me question what I was reading. endWith looks awesome but I hope it isn't affected by #254
Most helpful comment
@wldcordeiro in v6 there is no concat pipeable operator anymore so _that code_ as-is doesn't work but the static factory function usage does:
6.2 now has a
endWithoperator that makes this easier as well: