redux-utilities / redux-promise

FSA-compliant promise middleware for Redux.
MIT License
2.67k stars 120 forks source link

Should redux-promise return the original promise instead of the result of promise.then() ? #23

Open Qrysto opened 8 years ago

Qrysto commented 8 years ago

This is the case: in my components I want to do some custom actions depends on whether the api call succeeds or fails, like redirecting or showing some messages. I want something like this

dispatch(someFSAAsyncAction).then(onResolve).catch(onReject);

But the problem is redux-promise returns the result of the promise.then() instead of the original promise itself, and according to the answers here http://stackoverflow.com/questions/34222818/native-promise-chaining-with-catch, then the promise i receive from dispatch will always go to onResolve and never onReject (in case of error it will resolve an undefined result). So should redux-promise return the original promise so that we can register then() and catch() to the returned result of dispatch()?

eimfach commented 8 years ago

+1

mbensch commented 8 years ago

If I dispatch an async action, the dispatch() method will return a promise which, when resolved, will contain the original action. If you use redux-actions you can then inspect the action if it has error = true set and you know that your original promise was rejected.

Here's some sample code that will demonstrate that:

import { createStore, applyMiddleware } from 'redux';
import promiseMiddleware from 'redux-promise';
import RSVP from 'rsvp';
import { createAction, handleAction } from 'redux-actions';

const reducer = handleAction('TEST_ASYNC', (state = {}, action) => (
  Object.assign({}, state, { payload: action.payload })
));

const store = createStore(reducer, applyMiddleware(promiseMiddleware));

const promise = new RSVP.Promise((resolve, reject) => {
    const rand = Math.ceil((Math.random() * 10) + 1);
    console.log(rand);
    if (rand % 2 === 0) {
      setTimeout(() => {
        resolve("resolved");
      }, 1000);
    } else {
      reject("rejected");
    }
  });

const action = createAction('TEST_ASYNC');

const dispatchResult = store.dispatch(action(promise));

console.dir(dispatchResult);

dispatchResult.then((result) => {
  if(result.error) {
    console.log(`Promise was rejected with payload: ${result.payload}`)
  } else {
    console.log(`Promise was resolved with payload: ${result.payload}`)
  }
});
dreampulse commented 7 years ago

+1