Redux-promise not resolving a promise when in the action there is a number

910 views Asked by At

I am currently developing an application that is a copy of Instagram. It works with React-Redux, calls an external API via axios to fetch photos that are actually blog posts. I need to also pass the amount of likes (so 0) for each one, that I am adding in my fetchPhotos action creator, which causes my application to crash. This works fine whenever the action creator is only returning type and payload.

When I console logged the action it actually turned out that the promise is now not being resolved and thus followed the error.

Action creator:

 export function fetchPhotos() {
  const response = axios.get("https://dog.ceo/api/breed/husky/images");
  return {
    type: FETCH_PHOTOS,
    payload: response,
    likes: 0
  };
}

Reducer:

export default function(state = [], action) {  
  switch(action.type) {
    case FETCH_PHOTOS:
    console.log(action);
      return [action.payload.data.message, action.likes];
    default:
      return state;
  }  
}

In App:

const history = createBrowserHistory();

const store = createStore(
  connectRouter(history)(reducers),
  compose(applyMiddleware(routerMiddleware(history), ReduxPromise))
);

Is there any way to make the action creator actually resolve this promise inside the action.payload?

2

There are 2 answers

0
llievredemars On BEST ANSWER

For documentation:

As @fshauge mentioned, the payload has to be a promise and adding the property of likes breaks it. I found this in the issues, which has solved my issue. The likes property actually has to go into meta, so the end result that functions correctly is:

export function fetchPhotos() {
  const response = axios.get("https://dog.ceo/api/breed/husky/images");
  return {
    type: FETCH_PHOTOS,
    payload: response,
    meta: {
      likes: 0
    }
  };
}
1
fshauge On

According to the documentation of redux-promise, it expects either a promise or a Flux Standard Action (FSA) where the payload is a promise. Since adding the 'likes' property breaks FSA-compliancy, it has to be inside the payload somehow.

I suggest returning a promise directly from the action creator with the 'likes' property embedded as follows:

export async function fetchPhotos() {
  const response = await axios.get("https://dog.ceo/api/breed/husky/images");
  return {
    type: FETCH_PHOTOS,
    payload: {
      data: response.data,
      likes: 0
    }
  };
}

redux-promise will automatically call dispatch when the promise resolves, and you can use the following code in your reducer:

export default function (state = [], action) {
  switch (action.type) {
    case FETCH_PHOTOS:
      console.log(action);
      return [action.payload.data.message, action.payload.likes];
    default:
      return state;
  }
}