I was curious if there is a way to pass a parameter to a middleware without retrieving it from the state. What I want to do is to pass a generic function that we are using that determines if the user is authenticated or not. So rather than retreiving the authentication information from the state which will be code duplication, I want to pass isAuthenticated
function to the middleware.
I don't think this is implemented natively in applyMiddleware
framework but maybe someone has a work around for this situation.
Ok the right way to do this turned out to be a wrapper function that will wrap the actual middleware function
export const middlewareFunction = (store) => (next) => (action) => {
do some stuff with something...
}
If this is your actual middleware function, than you should be applying the middleware as
applyMiddleware(middlewareFunction);
What you should be doing to pass a parameter is to implement a function like
export const middlewareWrapper = (args) => {
do some stuff with your args
return (state) => (next) => (action) => {
do more stuff with your args and actions
}
}
With this syntax you can apply the middleware as :
applyMiddleware(middlewareWrapper(args));
Since actions passed to middleware don't have to be pure, you can pass a function as part of the action. Since the middleware has an access to the store, and using store.getState()
to the state, we can apply the method to the state, and get a computed result.
In the api middleware from the real world example of redux you can see that the endpoint
can be a function, and the actual endpoint can be computed from state (see the code between the asterisks comments):
export default store => next => action => {
const callAPI = action[CALL_API]
if (typeof callAPI === 'undefined') {
return next(action)
}
let { endpoint } = callAPI
const { schema, types } = callAPI
/***************************************************************************/
/** if the endpoint is a function compute the actual endpoint from state ***/
if (typeof endpoint === 'function') {
endpoint = endpoint(store.getState())
}
/***************************************************************************/
if (typeof endpoint !== 'string') {
throw new Error('Specify a string endpoint URL.')
}
if (!schema) {
throw new Error('Specify one of the exported Schemas.')
}
if (!Array.isArray(types) || types.length !== 3) {
throw new Error('Expected an array of three action types.')
}
if (!types.every(type => typeof type === 'string')) {
throw new Error('Expected action types to be strings.')
}
function actionWith(data) {
const finalAction = Object.assign({}, action, data)
delete finalAction[CALL_API]
return finalAction
}
const [ requestType, successType, failureType ] = types
next(actionWith({ type: requestType }))
return callApi(endpoint, schema).then(
response => next(actionWith({
response,
type: successType
})),
error => next(actionWith({
type: failureType,
error: error.message || 'Something bad happened'
}))
)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With