Skip to content

Merge guard and sample methods #521

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

Closed
val-o opened this issue Sep 5, 2021 · 3 comments
Closed

Merge guard and sample methods #521

val-o opened this issue Sep 5, 2021 · 3 comments
Labels
core effector package enhancement New feature or request RFC Request for Comments

Comments

@val-o
Copy link

val-o commented Sep 5, 2021

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 once submitPasswordEvent is fired, but only when AuthFlowState is in the right state
  • Then we need to collect username from AuthFlowState and password from submitPasswordEvent params in order to call a submitPassowrdFx 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,
});
@val-o val-o added the RFC Request for Comments label Sep 5, 2021
@doasync
Copy link
Member

doasync commented Sep 6, 2021

@zerobias
Copy link
Member

zerobias commented Sep 6, 2021

The reason why fn is still missing in guard is purely technical - it is quite difficult to write types for guard, so we have not yet succeeded in implementing this feature

@zerobias zerobias added core effector package enhancement New feature or request help wanted Extra attention is needed labels Sep 6, 2021
@zerobias
Copy link
Member

guard will be merged with the sample in the next minor release. right now I am working on types for this feature

@zerobias zerobias removed the help wanted Extra attention is needed label Nov 24, 2021
@zerobias zerobias added this to the effector 22.2.0 milestone Nov 24, 2021
@zerobias zerobias changed the title Mapping function in guard method Merge guard and sample methods Jan 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core effector package enhancement New feature or request RFC Request for Comments
Projects
None yet
Development

No branches or pull requests

3 participants