svrcekmichal / redux-axios-middleware

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

Send filtered response to reducer as payload? #74

Closed sebmor closed 6 years ago

sebmor commented 6 years ago

Can we influence what the response returns as payload to the action?

For example I'm querying an API that returns a result with way more information that I needed, and I only want to use a single piece. Can I somehow filter after successfully receiving the raw response data, and sending only the data I need to the reducer with the _SUCCESS action?

sebmor commented 6 years ago

A way to do it is using thunks. Sending a 'dummy' action first, and the manually processing the response and sending a payload to be reduced. Brief example;

But I think it's either this or processing this data in the reducer, which is considered bad practise. Maybe a onSuccess callback per action could be useful to have instead of relying on thunks?


export const getLikeUserAction = (userUid) => (dispatch) => {
  return dispatch({
    type: 'GET_LIKE_INTERACTION',
    payload: {
      request: {
        method: 'GET',
        url: `/users/getInteraction?withUserUid=${userUid}`
      }
    }
  })
  .then((response) => {
    const result = response.payload.data.result
    // Check if the array is Empty (ie no interactions)
    if (isEmpty(result)) {
      return dispatch(fetchGetLikeUser(false))
    } else {
      if (find(result, ['toUserUid', userUid])) {
        return dispatch(fetchGetLikeUser(true))
      }
    }
  })
}
nmaves commented 6 years ago

I don't really understand the need or purpose?

sebmor commented 6 years ago

The API call is returning a whole slew of data, while I just want to set a store property flag true/false depending on some logic. I should handle this logic in the action creator.

Redux-axios-middleware doesn't allow me to change my response that is send down to the reducer, it always sends the raw response, forcing me to either use thunks or handle this logic in the reducer, unless I'm missing something?

nmaves commented 6 years ago

Have you tried a response interceptor?

I guess just don't see the harm in having the following in your reducer. Just ignore the rest of the crap in the response.

const { flagToPullFromResponse } = action.payload.data
sebmor commented 6 years ago

Interceptors are kind of meant to take care of general logic I guess, like adding a header, etc Not specific for 1 action?

It's just the API returns data in the style of this; which is not what I want to save in the store.

{
    "result": [
        {
            "fromUserUid": "2ffe0bea-9214-4306-a7b3-48b223f76021",
            "toUserUid": "02ae77ee-987f-4863-886b-3c38ae0738a8",
        },
        {
            "fromUserUid": "02ae77ee-987f-4863-886b-3c38ae0738a8",
            "toUserUid": "2ffe0bea-9214-4306-a7b3-48b223f76021",
        }, ...
    ]
}

From that data I want to derive true/false. I guess maybe my use case is too specific, and I should try to get the API to send a cleaner response, or just handle it inside the reducer, although redux-guys advise against that.

Anyhow thank you for your response already

nmaves commented 6 years ago

There is absolutely nothing wrong with massaging the data in a reducer before you return the new state. Every API out there is different and they all find ways to mess up the data/structure coming back from them :)