svrcekmichal / redux-axios-middleware

Redux middleware for fetching data with axios HTTP client
MIT License
920 stars 96 forks source link

[Question] how to use this together with redux-thunk? #58

Closed nealoke closed 7 years ago

nealoke commented 7 years ago

Hi, I'm currently looking for a way to reduce much duplicate code from my action creators and I think this project could help me.

I'm currently using redux-thunk for all my async action creators. Is it possible to dispatch a standard action when a request fails?

nmaves commented 7 years ago

Shoot me an example of one of your thunks and I can help you out.

nealoke commented 7 years ago

Here is an example of my thunk. Be aware that the first dispatch is handled by middleware which allows batching actions. When a request would fail I would love to have a standard action that will be dispatched (see .catch())

export const fetchSomeStuff = (requestArray) => (dispatch) => {
    dispatch(requestArray.map(item => requestItem(item)));

    new Promise(resolve => setTimeout(resolve, 500))
        .then(() => {
            dispatch(/* stuff */);
            return request;
        })
        .catch((error) => dispatch(standardErrrorAction(error)));
};
nmaves commented 7 years ago

Okay your code is a bit strange as you are not returning your promise. Why are you using a timeout? Try to give a real world example. Are you trying to understand just how this middleware works in general or a specific use case for you?

nealoke commented 7 years ago

@nmaves sorry for the confusion, I'm using the timeout for simulating network delay and in my case I do return the promise... Don't know why I haven't included it in the example.

nmaves commented 7 years ago

Not sure I understand what you are looking for but I can take a stab at it. I can try and give you a complex example and see where we can go from there. Below is a thunk that returns a new Promise. Next, you can dispatch a login request. When that is complete we can issue two more requests in parallel and wait for their results to then finally fulfill the original promise with the user object from the first request.

export const login(username, password) {

  return (dispatch) => {
    return new Promise(resolve => {
      dispatch({
        type: 'LOGIN',
        payload: {
          request: {
            url: '/login'
          }
        }
      }).then(response => {
        const {
          user
        } = response.data
        Promise.all([
          dispatch({
            type: 'FETCH_USER_SETTINGS',
            payload: {
              request: {
                url: '/user/settings'
              }
            }
          }),
          dispatch({
            type: 'FETCH_USER_FAVORITES',
            payload: {
              request: {
                url: '/user/favorites'
              }
            }
          })
        ]).then(([
          userSettingsResponse,
          userFavoritesResponse
        ]) => {
          resolve(user)
        })
      })
    })
  }

}
nmaves commented 7 years ago

@nealoke does this answer your question?

nmaves commented 7 years ago

Closing this at there was no response from the OP.

nealoke commented 7 years ago

@nmaves sorry for the delayed response (was on vacation) :). But I kinda moved to simpler approach, so I'm not using this anymore. Thanks for the effort and time! 👍