redux-async-flow
This redux middleware allows dispatching async actions, that may include:
- promise
- array of promises, that will be chained
- functions returning promises
- array of functions returning prommises, that will be chained
- array of other async actions, that will be chained
- functions returning anything, that will be chained
- array of functions returning anything, that will be chained
It will handle errors in promises, dispatching ERROR actions. Exceptions, that occured in your reducer won't be swallowed and will be thrown.
Example
Lets say, you have some functions, returning promises for web api requests:
const apiLogin = { ;}; const apiPullUserProfile = { if userId === 15921 ; }; const apiPullAvatar = { if avatarUrl === "https://img.example.org/15921/Gc2xcYMvRieoA8.png" ; };
You can make corresponding actions creators:
const startLoggingIn = types: "LOGGING_IN_STARTED" "LOGGING_IN_SUCCESS" "LOGGING_IN_ERROR" payload: ; const startPullingProfile = types: "PULLING_PROFILE_STARTED" "PULLING_PROFILE_SUCCESS" "PULLING_PROFILE_ERROR" payload: ; const startPullingAvatar = types: "PULLING_AVATAR_STARTED" "PULLING_AVATAR_SUCCESS" "PULLING_AVATAR_ERROR" payload: ;
Now you can make one action creator to rule them all:
const startEverything = types: "EVERYTHING_STARTED" "EVERYTHING_SUCCESS" "EVERYTHING_ERROR" payload: startPullingProfile startPullingAvatar ;
That will results in creating actions in the following order:
{ type: EVERYTHING_STARTED }
{ type: LOGGING_IN_STARTED }
{ type: LOGGING_IN_SUCCESS, payload: 15921 /* userId */ }
{ type: PULLING_PROFILE_STARTED }
{ type: PULLING_PROFILE_SUCCESS, payload: "https://img.example.org/15921/Gc2xcYMvRieoA8.png" /* avatarUrl */ }
{ type: PULLING_AVATAR_STARTED }
{ type: PULLING_AVATAR_SUCCESS, payload: /* avatar */ }
{ type: EVERYTHING_SUCCESS }
You can transform data in the midle of chain, lets replace https
with http
:
const startEverything = types: "EVERYTHING_STARTED" "EVERYTHING_SUCCESS" "EVERYTHING_ERROR" payload: startPullingProfile url startPullingAvatar ; // Or even asynchronously: const startEverything = types: "EVERYTHING_STARTED" "EVERYTHING_SUCCESS" "EVERYTHING_ERROR" payload: startPullingProfile { ; } startPullingAvatar ;
Any questions, propositions, pull requests are welcome in issues.