Dispatching a thunk from a middleware results in an error

76 views Asked by At

I have a thunk defined in my actions.js file:

export const myThunk = (param1, param2, param3) => {
   return dispatch => {
      dispatch({type: types.myThunkType})
      fetch(`https://mockurl.com?param1=${param1}&param2=${param2}&param3=${param3}`)
      .then(response => response.json())
      .then(data => {
         dispatch({type: types.everythingsAllRight, payload: data.results})
      })
   }
}

When I dispatch this from a React component, everything works like a charm. In my component.js we have something like this:

import myThunk from './actions/actions.js'
const dispatch = useDispatch()

return (
   <button onClick={() => {dispatch(myThunk(props.param1, props.param2, props.param3)}>
)

But when I try to use this same thunk from a middleware, like this:

   store.dispatch(anPlainObjectActionDefinedInActionsJsToo(param1, param2, false))
   .then(() => { 
      store.dispatch({
         type: types.anotherImportantActionType,
         payload: {
            thisData: someData,
            thatData: someOtherData
         }
      })
   })
   .then(store.dispatch(myThunk(param1, param2, param3)))

I get this error:

Unhandled Rejection (Error): Actions must be plain objects. Use custom middleware for async actions.

The error is hiting the middleware that deals with action types myThunkType:

Unhandled Rejection (Error): Actions must be plain objects. Use custom middleware for async actions.
▶ 3 stack frames were collapsed.
(anonymous function)
src/Store/middleware/middlewareThatDealsWithMyThunkTupeActionType.js:9
   6 | }
   7 | if (action.type !== types.myThunkType &&
   8 |    action.type !== types.anotherType) {
>  9 |    return next(action)
     | ^  10 | }
  11 | 

As it can't "return next action". Any hints of what I'm doing wrong?

EDIT: Inspecting in debug, I found that the dispatched thunk appears like that when it hits the middleware: https://i.stack.imgur.com/YL215.jpg

1

There are 1 answers

4
Orinayo Oyelade On BEST ANSWER

You need to pass a function to your .then but not immediately call it like you currently do. Also, change your middleware to use currying to pass dispatch and create a closure. Rewrite the final then block to

.then(() => {
store.dispatch(myThunk(param1, param2, param3))
})

You can read more about custom redux middleware and currying here