4

In redux async actions in the docs the state of an async request is kept as a property isFetching in the state container for various objects:

{
  selectedSubreddit: 'frontend',
  postsBySubreddit: {
    frontend: {
      isFetching: true,
      didInvalidate: false,
      items: []
    },
    reactjs: {
      isFetching: false,
      ...

This works fine however I'm looking to build out my application and I'm looking for design patterns that will scale up across multiple objects that must be kept in my state container and synchronized with my api. So I'm looking for standards or libraries that the redux community have adopted.

I found the Flux Standard Action which looks quite reasonable but this is more a standardization of how to handle payloads and errors, not the status of an async request.

Is there any library or pattern that a lot of redux developers are working with? I would think there might be something like { success, isFetching, error }.

jcroll
  • 6,875
  • 9
  • 52
  • 66
  • 3
    I created a function that when called produces a reducer having the following structure: `{ inProgress, succeeded, failed, failureReason }`. The function takes as arguments the names of actions that map to an "in progress", "success" and "failure" event. Kind of like a higher order reducer if you will. Handy for reuse. – ctrlplusb Oct 06 '16 at 17:16
  • 1
    http://slides.com/omnidan/hor#/ – ctrlplusb Oct 06 '16 at 17:18

2 Answers2

3

Take a look at this library, use it like you want.

In my app I have use it like that, first you add it to your middleware in the store configuration. After this one you setup your action to be a promise and the payload is the promise.

export const reqAllGames = games => {

  const promise = new Promise((resolve, reject) => {
    request
      .get(`${config.ROOT_URL}/${config.API_KEY}`)
      .end((err, res) => {
        if (err) {
          reject(err);
        } else {
          resolve(res.body.top);
        }
      });
  });

  return {
    type:    types.RECEIVE_ALL_GAMES,
    payload: promise
  };

};

After your can setup your reducer like:

const gameReducer = (games = { isFetched: false }, action) => {

  switch (action.type) {
    case `${types.RECEIVE_ALL_GAMES}_PENDING`:
      return {};
    case `${types.RECEIVE_ALL_GAMES}_FULFILLED`:
      return {
        games:     action.payload,
        err:       null,
        isFetched: true
      };
    case `${types.RECEIVE_ALL_GAMES}_REJECTED`:
      return {
        games:     null,
        err:       action.payload,
        isFetched: true
      };
    default:
      return games;
  }

};

Hope that can help ;)

EQuimper
  • 5,811
  • 8
  • 29
  • 42
  • 1
    I am going to try the [Flux Standard Action Redux Promise](https://github.com/acdlite/redux-promise) but I will mark this question as accepted as it introduces using promises in actions to manage async state. Thanks EQuimper – jcroll Oct 18 '16 at 16:35
1

Yep, there's a very wide variety of addons for Redux, and many of those related to async behavior. My Redux addons catalog lists pretty much all of them. There's middlewares for handling async behavior, utilities to generate actions describing async work, prebuilt libs to track request status, and more.

markerikson
  • 63,178
  • 10
  • 141
  • 157