Replies: 1 comment 2 replies
-
|
Is this what you had in mind #4980? |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Context
I'm using
rxMethodfrom@ngrx/signalsfor async operations in my signal stores (auth, API calls, etc.).rxMethodis fire-and-forget by design. But sometimes the caller (a component, a guard, a form) needs to know whether the operation succeeded or failed, e.g. to navigate after login, show a toast, or close a dialog.What I came up with
I created an
AsyncHandlerinterface that gets mixed into therxMethodinput via intersection:Usage in a store:
Calling from a component:
What I like about it
rxMethodkeeps its core strengths: flow control (exhaustMapto prevent duplicate submissions) and centralized state management (isLoading, etc.) all live in the store where they belongAsyncHandlerjust adds an optional escape hatch for the caller, without changing any of that& AsyncHandleron the typesignInError,signInSuccess) to manage for one-shot operationsWhat worries me
It might be fighting against the reactive philosophy of signals, rxMethod, etc. Let me explain:
My questions
rxMethodto encapsulate async flows inside the store — but then I punch a hole through it with callbacks so the caller gets result feedback. It feels like I'm saying "the store owns the flow" and "but the component still needs to know what happened" at the same time. Is that a valid trade-off, or a sign that I'm using the wrong tool?rxMethodthat I'm missing?Alternatives I considered
Before landing on
AsyncHandler, I explored other approaches:Store error state (
signInErrorsignal): the store holds the error and the component reacts to it. But this requires the component to callstore.clearError()on init to avoid stale errors from a previous interaction. It also gets messy when multiple operations can fail — you end up withsignInError,createAccountError, etc.effect()on error signals: watching an error signal witheffect()to trigger side effects (toast, navigation). Buteffect()fires on every change, making it hard to distinguish "new error just happened" from "error is still there from last time". It also couples the component to the store's internal state shape.Event emitters / Subject: exposing a
Subject<Error>or similar from the store. This works but feels like reinventing callbacks with extra steps, and leaks reactive plumbing outside the store.AsyncHandlerfelt like the simplest option: one-shot callbacks scoped to a single call, no cleanup needed, no stale state.Any feedback or alternative approaches would be appreciated!
Beta Was this translation helpful? Give feedback.
All reactions