1

Does react flux architecture have something similar to Angular's interceptor where you can redirect 401 errors to the login page?

Shih-Min Lee
  • 9,350
  • 7
  • 37
  • 67
  • 1
    The Flux pattern doesn't really deal with ajax request handling, or even HTTP. It's a pattern for handling data flow within an app. Most Flux apps/libs I have seen deal with async data requests the "action creators", though. But it falls outside of Flux's concern how to actually fetch the data or handle HTTP. – Hannes Johansson Jul 06 '15 at 19:06

1 Answers1

3

Not specifically, but you can handle it in your ajax request error callback. Check for a 401 response, render your login component/redirect to login. With facebook's flux implementation i've typically kept my ajax calls inside the actions. The success callback invokes the dispatcher. I use react-router, so i could simply go to the login:

var MyActions = {
  doSomething: function () {
    $.post('/projects/new', {

    }).done(function (res) {
      AppDispatcher.handleViewAction({
        actionType: ProjectConstants.PROJECT_CREATE,
        data: res
      });
    }).fail(function (res) {
      AppDispatcher.handleViewAction({
        actionType: ProjectConstants.UNAUTHORIZED
      });
    });
  }
};

In the store, i handle the unauthorized response:

var _unAuth = false;

var MyStore = {
  getUnauthorized() {
    return _unAuth;
  },
  setUnauthorized(val) {
    _unAuth = val;
  }
}

AppDispatcher.register(function(payload) {
  var action = payload.action;
  if (action.actionType === ProjectConstants.UNAUTHORIZED) {
    ProjectStore.setUnauthorized(true);
  }
});

Then in the component invoke the redirect since it has react router scope:

class MyComponent extends Component {
  _onChange() {
    if (ProjectStore.getUnauthorized()) {
      this.transitionTo('/login');
    }
  }
}

Though if you want to do a typical page redirect, you can invoke window.location.href = '/login'; inside the action.

You can abstract it a bit better by putting login state into a separate store. Which is what i've done in my app. I was just trying to keep it simple, reduce number of classes & singletons.

Edit To handle all ajax requests:

I'd just write a wrapper around my ajax library:

var ajax = {
  send: function (url, data, success, fail) {
    $.post(url, data).done(success).fail((jqXHR, textStatus, errorThrown) => {
      if (jqXHR.status === 401) {
        location.href = '/login';
      }
      else {
        fail(jqXHR, textStatus, errorThrown);
      }
    });
  }
}

Invoke that instead of the ajax library directly.

Something i haven't tried, but you could potentially pass the component this down to the function through your action call. Use that to invoke things like transitionTo but that feels unclean to me.

agmcleod
  • 13,321
  • 13
  • 57
  • 96
  • yes but the thing is I have 100 actions that POSTs to the backend API server so I have to do this site-wise instead of on per-action basis. – Shih-Min Lee Jul 06 '15 at 12:57
  • Using a wrapper around the ajax calls that knows about "/login" is breaking modularization in my opinion. There must be a better solution. – Juan Ibiapina Feb 03 '17 at 16:27