redux-promise-listener
v1.1.1
Published
A Redux middleware that allows actions to be converted into Promises
Downloads
11,816
Readme
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.js
import { createStore, applyMiddleware } from 'redux'
import createReduxPromiseListener from 'redux-promise-listener'
const reduxPromiseListener = createReduxPromiseListener()
const store = createStore(
reducer,
initialState,
applyMiddleware(...otherMiddleware, reduxPromiseListener.middleware)
)
export const promiseListener = reduxPromiseListener // <---- ⚠️ IMPORTANT ⚠️
export default store
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.js
import { promiseListener } from './store.js'
const generatedAsyncFunction = promiseListener.createAsyncFunction({
start: 'START_ACTION_TYPE', // the type of action to dispatch when this function is called
resolve: 'RESOLVE_ACTION_TYPE', // the type of action that will resolve the promise
reject: 'REJECT_ACTION_TYPE' // the type of action that will reject the promise
})
// 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.asyncFunction(values).then(
// called with action.payload when an action of
// type 'RESOLVE_ACTION_TYPE' is dispatched
resolvePayload => {
// do happy stuff 😄
},
// called with action.payload when an action of
// type 'REJECT_ACTION_TYPE' is dispatched
rejectPayload => {
// do sad stuff 😢
}
)
// when done, to prevent memory leaks
generatedAsyncFunction.unsubscribe()
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
.