Skip to content

Instantly share code, notes, and snippets.

@andyjessop
Last active September 12, 2022 09:58
Show Gist options
  • Save andyjessop/e7ff13fa51c7c6d0ea2e854f01dbfbfc to your computer and use it in GitHub Desktop.
Save andyjessop/e7ff13fa51c7c6d0ea2e854f01dbfbfc to your computer and use it in GitHub Desktop.
Slice config with async handlers
export function authModule(authHttpApi: Auth, toaster: Toaster) {
return createSlice('auth', {
// In order to update the state, return a new state just as in a normal reducer.
// [name]: (state: S, Payload | Action) => S
// But if you want to make side effects, just return an async function instead of the state.
// The async function is passed a context with the API of the current slice.
// [name]: (state: S, Payload | Action) => async ({ api }) => {
// ...side effects
// },
login: (state: AuthState, { username, password }) => async ({ api }) => {
try {
const res = await authHttpApi.login(username, password);
if (!res) {
return api.loginFailure();
}
api.loginSuccess(username);
toaster.toast({
message: `You are logged in as ${username}`,
type: 'success',
});
} catch (e) {
auth.loginFailure();
toaster.toast({
message: `Login failed`,
type: 'error',
});
}
},
loginFailure: (state: AuthState) => merge({
username: null,
}),
loginSuccess: (state: AuthState, { username }) => merge({
username,
}),
logout: () => async ({ api }) => {
try {
const res = await authHttpApi.logout();
api.logoutSuccess();
toaster.toast({
message: 'You are logged out',
type: 'success',
});
} catch (e) {
api.logoutFailure();
toaster.toast({
message: 'Logout failed',
type: 'error',
});
}
},
logoutFailure: () => async() => {},
logoutSuccess: (state: AuthState) => merge(state, {
username: null,
}),
});
}
// `api` calls `dispatch` with the action
const { actions, api, reducer } = authModule(auth, toaster);
dispatch(actions.login({ username, password }));
// or
api.login({ username, password });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment