goatslacker / alt

Isomorphic flux implementation
http://alt.js.org/
3.45k stars 321 forks source link

Error handler does not get triggered for ajax calls #709

Open hrushi53 opened 7 years ago

hrushi53 commented 7 years ago
const ApplicationSource = {
 withdrawApplication: {
    remote (state, application) {
      return $.ajax({url: 'somepath', method: 'GET'});
    },
    success: applicationActions.withdrawApplicationSuccess,
    error: applicationActions.withdrawApplicationFailure,
  }
}

Whenever /somepath returns a 200 it is handled by the success handler 'withdrawApplicationSuccess' but a non-200 (for ex 500 or 404), is not handled by error handler 'withdrawApplicationFailure'.

Note We are using jquery 1.11. So I am assuming the $.ajax returns a Promise.

Is there anything wrong with this?

snags88 commented 7 years ago

@hrushi53 could you also post the code for your action of withdrawApplicationFailure? I've found that you need to explicitly dispatch the error instead of just return error on failure cases:

class applicationActions {
  withdrawApplicationSuccess(data) {
    return data; // Implicit dispatch
  }

  withdrawApplicationFailure(error) {
    return (dispatch) => dispatch(error); // Explicit dispatch
  }
}

Not sure if this will resolve your issue, but worth a shot.

hrushi53 commented 7 years ago

application_actions.es6

class ApplicationActions {
  constructor() {
    this.generateActions( 'withdrawApplicationSuccess', 
               'withdrawApplicationFailure');
  }
}
var applicationActions = alt.createActions(ApplicationActions);

application_source.es6

const ApplicationSource = {
 withdrawApplication: {
    remote (state, id) {
      return $.ajax({url: `somepath/${id}`, method: 'GET'});
    },
    success: applicationActions.withdrawApplicationSuccess,
    error: applicationActions.withdrawApplicationFailure,
  }
}

application_store.es6

class ApplicationStore {
  constructor() {
    this.bindActions(applicationActions);
    this.registerAsync(ApplicationSource);
  }

  onWithdrawApplicationSuccess(withdrawApplicationSuccess) {
    console.log(submitApplicationSuccess);
  }

 // THIS IS NEVER CALLED
  onWithdrawApplicationFailure(errorMessage) {
    console.log(errorMessage);
  }
}
var applicationStore = alt.createStore(ApplicationStore, 'ApplicationStore');

I am calling this from my react component, like this

applicationStore.withdrawApplication("someId");

snags88 commented 7 years ago

@hrushi53 I believe generateActions basically is the shortcut of passing the argument of your action function and using it as the return value. Since it seems like an issue with how the error can't get dispatched by a simple return AND the maintainer of Alt is AWOL, your best bet for now is to try creating the problematic action explicitly:

// application_actions.es6

class ApplicationActions {
  constructor() {
    this.generateActions( 'withdrawApplicationSuccess');
  }

  withdrawApplicationFailure(error) {
    return (dispatch) => dispatch(error); // Explicit dispatch
  }
}
var applicationActions = alt.createActions(ApplicationActions);

Try it out and let me know if that helps.

DEllement commented 7 years ago

Add same issue in one of my app returning the explicit dispatch did the trick,

return (dispatch) => dispatch(error);

Thanks!