Redux Async flows

Enhance async await thunks with take functionality and allow them to wait for redux actions.

Pause function execution waiting for
user interactions
to compose centralized user flows.

Aync Flows setup

import createAsyncFlowsMiddleware from 'redux-async-flows';
import thunk from 'redux-thunk';
import { createStore, applyMiddleware } from 'redux';
const { take, asyncFlowsMiddleware } = createAsyncFlowsMiddleware();
const store = createStore(
reducer,
applyMiddleware(asyncFlowsMiddleware, thunk.withExtraArgument(take))
);

With take feature you can unify multiple thunks into a single async function.

Purchase User flow example         ➡️

Async Flows

import * as actions from "../actions";
import { getAvailableColors } from '../utils';
const { userInteractionTypes: user, uiActions: ui } = actions;
export const userFlow = () => async (dispatch, getState, take) => {
dispatch(ui.showItems());
const { payload: { item } } =
await take(user.SELECT_ITEM);
dispatch(actions.itemSelected(item));
dispatch(ui.sidebarLoading(true));
dispatch(ui.openSidebar());
const availableColors = await getAvailableColors(item);
if(item === 'shirts') {
dispatch(actions.storeShirts(availableColors));
} else {
dispatch(actions.storeJeans(availableColors));
}
dispatch(ui.sidebarLoading(false));
await take(user.SELECT_COLOR);
dispatch(ui.closeSidebar());
dispatch(ui.openModal());
await take(user.CONFIRMATION);
dispatch(ui.closeModal());
dispatch(ui.resetState());
};

Simple User flow

Thunk

import * as actions from "./actions";
import { categoriesService } from './utils';
const { uiActions: ui } = actions;
export const userStartsFlow = () => (dispatch, getState) => {
dispatch(ui.showCategories());
};
export const categorySelected = () =>
async (dispatch, getState) => {
const { selected } = getState().categories;
dispatch(ui.sidebarLoading(true));
dispatch(ui.openSidebar());
const items = await categoriesService(selected);
if (selected === 'flights') {
dispatch(actions.storeFlights(items));
} else {
dispatch(actions.storeHotels(items));
}
dispatch(ui.sidebarLoading(false));
};
export const optionSelected = () => (dispatch, getState) => {
dispatch(ui.closeSidebar());
dispatch(ui.openModal());
};
export const operationConfirmation = () => (dispatch, getState) => {
dispatch(ui.closeModal());
dispatch(ui.resetState());
};

Simple User flow