4

I am using Axios, Redux and Redux Promise Middleware.

I have the following action creator:

return {
        type: 'FETCH_USERS',
        payload: axios.get('http://localhost:8080/users',
            {
                params: {
                    page
                }
            }
        )
    }

In my reducer for the FETCH_USERS_PENDING action, I would like to save the requested url in my state. How can I do this?

Patrick Burtchaell
  • 4,112
  • 1
  • 14
  • 25
Baz
  • 12,713
  • 38
  • 145
  • 268

2 Answers2

14

You want to use redux-promise-middleware's "meta" variable. Like so:

return {
  type: 'FETCH_USERS',
  meta: { url: 'http://localhost:8080/users' },
  payload: axios.get('http://localhost:8080/users', config)
}

You could pass it through in your params, but that won't be returned until the page is fetched. Which means it won't be passed back during FETCH_USERS_PENDING.

And I'm pretty sure if you include directly in the return object (like how Lucas suggested), it will be stripped out of the FETCH_USERS_PENDING stage.

Here's the FETCH_USERS_PENDING stage from redux-promise-middleware:

  /**
   * First, dispatch the pending action. This flux standard action object
   * describes the pending state of a promise and will include any data
   * (for optimistic updates) and/or meta from the original action.
   */
  next({
    type: `${type}_${PENDING}`,
    ...(data !== undefined ? { payload: data } : {}),
    ...(meta !== undefined ? { meta } : {})
  });

As you can see during this stage, the middleware returns the appended "type" attribute and it checks for "data" & "meta" attributes. If present, they are passed along within the action.

Here's the redux-promise-middleware source code if you want to look into it further.

James Rutledge
  • 191
  • 1
  • 7
0

Simply pass the URL in the action as well:

return {
  type: 'FETCH_USERS',
  url: 'http://localhost:8080/users',
  payload: axios.get('http://localhost:8080/users', {
    params: {
      page
    }
  }
}

and access it in the reducer with action.url. Or you can leave the action as it is, and access it in the promise resolution:

action.payload.then(function(response) {
  var url = response.config.url;
});
Lucas
  • 4,067
  • 1
  • 20
  • 30
  • 1
    Adding arbitrary keys at action's top level makes it non-[FSA-compliant](https://github.com/acdlite/flux-standard-action). @James Rutledge's answer correctly suggests putting the url under the `meta` key instead. – Nic Nilov Jun 14 '17 at 22:47