-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(component-store): add tapResponse operator #2763
Conversation
FYI, we've been using this operator within Firebase Console for some time already 🙂 so this is pushing it upstream. Also, if there are any other preferences around the naming - I'm all ears 🙂 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About the naming, what about mapResponse
?
Reasoning, what is handle
, and map
feels RxJS-y.
Preview docs changes for 3b25f3c at https://previews.ngrx.io/pr2763-3b25f3c1/ |
@timdeschryver |
That's a good point @markostanimirovic |
export function mapResponse<T>( | ||
nextFn: (next: T) => void, | ||
errorFn: (error: unknown) => void, | ||
completeFn?: () => void | ||
): (source: Observable<T>) => Observable<T> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest to add two signatures for this function, similar to tap
operator in order to make it more flexible.
export function tap<T>(next?: (x: T) => void, error?: (e: any) => void, complete?: () => void): MonoTypeOperatorFunction<T>;
export function tap<T>(observer: PartialObserver<T>): MonoTypeOperatorFunction<T>;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The goal is to not make it flexible. I want to force to handle the error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I suggested that based on the implementation. According to the operator implementation too, I suggest the name safeTap or something similar. 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @markostanimirovic that's a good suggestion.
We had similar discussions about safeCall
operator for @ngrx/effect
and eventually called it mapToAction
and then renamed to act
: #1224
Looking at the poll tapResponse
appears to be the clear winner.
@beeman, technically this operator still maps
, but only the error case :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alex-okrushko
Naming - the hardest thing 😄
I would also choose tapResponse
between tapResponse
, mapResponse
and handleResponse
.
Response
as a part of name confused me a little bit, because it associates me with HTTP response 🙂
cd4adfe
to
047b17e
Compare
so |
I was thinking the same thing @alex-okrushko Sorry for not helping, naming things is hard... |
My 2 cents, I think I like |
* feat(component-store): add handleResponse operator * Rename to mapResponse * rename to tapResponse
Hi, can you observe this solution for tapResponse operator export function tapResponse<T>(
nextFn: (next: T) => void,
errorFn: (error: unknown) => void,
completeFn?: () => void
): (source: Observable<T>) => Observable<T> {
return (source) =>
source.pipe(
tap(nextFn),
catchError((error) => {
errorFn(error);
return EMPTY;
}),
finalize(completeFn || noop)
);
} |
Hi @Ash-kosakyan |
Hi @alex-okrushko /**
* Effects
* */
readonly loadAll = this.effect((origin$: Observable<void>) =>
origin$.pipe(
tap(() => this.setLoading(true)),
concatMap(() =>
this.modelService.getAll().pipe(
tap((models) => {
this.setAll(models);
}),
catchError((error: HttpErrorResponse) => {
this.setError(error.error);
return EMPTY;
}),
finalize(() => {
this.setLoading(false);
})
)
)
)
); |
@Ash-kosakyan - that's true. That also means that Thanks for your input! Thanks again. |
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
Adds a simple wrapper around
tap
that handles success and error +catchError(() => EMPTY)
.The was some confusion as to whether
catchError(() => EMPTY)
was needed whentap({error: (error) => handleError(error)})
was used.To avoid such confusion and remove a bit of boilerplate around not letting effect collapse, I suggest to have this very thin operator.
If not used, this operator is 100% tree-shakable from the bundle.
Does this PR introduce a breaking change?
Other information