Reputation: 2989
Is there way to bind one error handler for ajax requests that performs by backbone.js?
My situation: I can get 401 (Unauthorized) at any time, so I need to show login popup.
Upvotes: 36
Views: 16751
Reputation: 3351
You can handle this via the jQuery .ajaxSetup method. We have an identical situation (backbone app which may get a 401 error at any time) and we handle it by using jQuery's ajaxSetup in the entry point of our app:
var appView = new AppView(options);
$.ajaxSetup({
cache: false,
statusCode: {
401: function () {
appView.signIn();
}
}
});
appView.render();
Backbone.history.start({ root: config.rootUrl, pushState: true });
This approach gives global error handling without the need to extend the Backbone base classes.
Upvotes: 10
Reputation: 9216
Use jQuery directly for this.
$(document).ajaxError(function (e, xhr, options) {
// do your stuff
});
You can do the same thing for CSRF in rails for exemple (using ajaxSend).
You can read more here: http://api.jquery.com/jQuery.ajax#advanced-options
Upvotes: 24
Reputation: 5535
What I found is possibly the "most right way" in Backbone:
var GeneralErrorView = Backbone.View.extend({
events: {
'ajaxError': 'handleAjaxError'
},
handleAjaxError: function (event, request, settings, thrownError) {
//...handling goes here
}
});
this.view = GeneralErrorView({el: document});
You can put any error handling logic without extending Models or Collections. Make use of Backbone.Events inside handler and transmit messages to other error handlers or something like that.
Upvotes: 15
Reputation: 6183
Backbone's sync triggers an 'error' event when errors occur. So one approach you could take is to extend Backbone's Model and Collection objects to add these add-on error checks. It would look something like this:
ErrorHandlingModel = Backbone.Model.extend({
initialize: function(attributes, options) {
options || (options = {});
this.bind("error", this.defaultErrorHandler);
this.init && this.init(attributes, options);
},
defaultErrorHandler: function(model, error) {
if (error.status == 401 || error.status == 403) {
// trigger event or route to login here.
}
}
});
OtherModel = ErrorHandlingModel.extend({
});
and you would do something similar for the Collection object. I haven't tested the above, but think its pretty close. Obviously, you would choose better class names. The init method just enables subclasses to get a chance to do their own initialization.
Upvotes: 25