Closed
Description
Proposal
Provide an ability to transform data from clock
and source
in guard
function.
Use case
Suppose we have a simple authentication flow, with following definitions
type UserName = string;
type Password = string;
type AuthFlowState = { type: 'WaitingUserName' } | WaitingPasswordState | { type: 'Done' };
type WaitingPasswordState = { type: 'WaitingPassword'; username: UserName };
declare const isWatingPassword: (state: AuthFlowState) => state is WaitingPasswordState;
const store$ = createStore<AuthFlowState>({ type: 'WaitingUserName' });
const submitPasswordEvent = createEvent<Password>();
type SubmitPasswordArgs = { password: Password; username: UserName };
const submitPassowrdFx = createEffect<SubmitPasswordArgs, unknown>();
guard({
clock: submitPasswordEvent,
source: store$,
filter: isWatingPassword,
target: submitPassowrdFx,
});
- The
submitPassowrdFx
should be called oncesubmitPasswordEvent
is fired, but only whenAuthFlowState
is in the right state - Then we need to collect username from
AuthFlowState
and password fromsubmitPasswordEvent
params in order to call asubmitPassowrdFx
effect.
The code snipper above won't compile, due to types mismatch, because we also need to pass password from clock. If we would have a mapping function (like fn
in sample
), which would be called after filtering, we could easily shape a params expected by target effect
Workaround
We can achieve desired behaviour by combining sample with guard as follows:
sample({
clock: guard({ clock: submitPasswordEvent, source: store$, filter: isWatingPassword }),
source: submitPasswordEvent,
fn: (sourceParams, clockParams): SubmitPasswordArgs => ({
password: sourceParams,
username: clockParams.username,
}),
target: submitPassowrdFx,
});