Redux Promise Listener
Redux Promise Listener generates an async function that will dispatch a start
action, and will resolve or reject the promise when a resolve
or reject
action is dispatched.
Libraries like redux-promise
or redux-promise-middleware
are useful for converting promises to actions. Redux Promise Listener does the inverse: converting actions to promises.
Why?
Most of the popular form libraries accept an onSubmit
function that is expected to return a Promise
that resolves when the submission is complete, or rejects when the submission fails. This mechanism is fundamentally incompatible with action management libraries like redux-saga
, which perform side-effects (e.g. ajax requests) in a way that does not let the submission function easily return a promise. Redux Promise Listener is a potential solution.
Usage
Step 1
Create and add the middleware as you would with any Redux middleware. Remember to export the middleware!
// store.jsimport createStore applyMiddleware from 'redux'import createReduxPromiseListener from 'redux-promise-listener' const reduxPromiseListener = const store = const promiseListener = reduxPromiseListener // <---- ⚠️ IMPORTANT ⚠️
Step 2
If you are using react-redux
, your Step 2 is over here.
...
Okay, now that those React nerds are gone...
Wherever you need an async function that dispatches one action and listens for others...
// someFile.jsimport promiseListener from './store.js' const generatedAsyncFunction = promiseListener // This structure is in the shape:// {// asyncFunction, <--- the async function that dispatches the start action and returns a Promise// unsubscribe <--- a function to unsubscribe from the Redux store// } // dispatches an action { type: 'START_ACTION_TYPE', payload: values }generatedAsyncFunction // when done, to prevent memory leaksgeneratedAsyncFunction
API
createListener: () => PromiseListener
The default export of this library. Creates a Redux middleware, but that also has a function on it called generateAsyncFunction
middleware.generateAsyncFunction: (config: Config) => AsyncFunction
Types
ActionMatcher: Action => boolean
A predicate with which to make decisions about Redux actions.
PromiseListener
An object with the following values:
middleware: Middleware
Redux middleware that should be used when creating your Redux store.
createAsyncFunction: (config: Config) => AsyncFunction
Takes a Config
and returns an object containing the async function capable of dispatching an action and resolving/rejecting a Promise upon the dispatch of specified actions, and a function to unsubscribe this listener from the Redux store.
Config
An object with the following values:
start: string
The type
of action to dispatch when the function is called.
resolve: string | ActionMatcher
The type
of action that will cause the promise to be resolved, or a predicate function that will return true
when given the type of action to resolve for.
reject: string | ActionMatcher
The type
of action that will cause the promise to be rejected, or a predicate function that will return true
when given the type of action to reject for.
setPayload?: (action: Object, payload: any) => Object
A function to set the payload (the parameter passed to the async function). Defaults to (action, payload) => ({ ...action, payload })
.
getPayload?: (action: Object) => any
A function to get the payload out of the resolve action to pass to resolve the promise with. Defaults to (action) => action.payload
.
getError?: (action: Object) => any
A function to get the error out of the reject action to pass to reject the promise with. Defaults to (action) => action.payload
.
AsyncFunction
An object with the following values:
asyncFunction: (payload: any) => Promise<any>
The async function that will dispatch the start action and return a promise that will resolve when the resolve action is dispatched or reject when the reject action is dispatched.
unsubscribe: () => void
A cleanup function that should be called when the async function is no longer needed.
⚠️ Failure to call unsubscribe()
may result in a memory leak. ⚠️
If you are using react-redux-promise-listener
, this is done for you on componentWillUnmount
.