I think I solved it myself. Check my interceptor that I posted as a solution below.
I was wondering if it would be possible to write an http interceptor that can let the caller know how the request is doing.
Right now, when I want to call my backend, I wrap an $http call in a wrapper that sets attributes on an object I pass it:
publ.wrap = function(f, ctrl){
ctrl.busy = true;
ctrl.error = false;
return f()
.then(function(res){
ctrl.busy = false;
ctrl.result = res;
return res;
}).catch(function(err){
ctrl.busy = false;
ctrl.error = err;
ctrl.result = undefined;
})
};
publ.login = function(args, ctrl){
publ.wrap(function(){
return $http.post('http://localhost:3001/authenticate', {
username : args.username,
password : args.password
}).then(function(jwt){
$cookies.put('token', jwt);
})
}, ctrl);
};
In this case, I call login(authArgs, $scope.loginCtrl)
in my login page controller. Then I use loginCtrl.busy
, loginCtrl.result
& loginCtrl.error
in my login template.
I pretty much want every call I make to the backend to set these attributes and make them available to the views that initiate the request.
Using a wrapper function like this gets the job done, but I'm wondering if it can be done using an interceptor? It feels to me like that would provide a much cleaner request flow that doesn't require me to explicitly wrap all of my backend calls in my services.
Now I read up on httpInterceptors, and can't seem to find a way to have them set attributes on a user-provided object. The closes thing I found was this article that has an example ( Timestamp Marker (request and response interceptors) ) where they add attributes to the config object in both the request
and response
interceptor stages.They don't show how to access the config object inside the responseError
stage or in the caller controller.
Any help would be greatly appreciated :)
I managed to get the interceptor working. Apparently we CAN access the config file in all interceptor phases:
/******************************************
SETUP BUSY/ERROR/DATA HTTP INTERCEPTOR
*******************************************/
.config(function($httpProvider){
$httpProvider.interceptors.push(function($q) {
return {
request : function(config) {
if(config.ctrl){
config.ctrl.busy = true;
config.ctrl.error = false;
config.ctrl.data = undefined;
}
return config;
},
response : function(response) {
if(response.config && response.config.ctrl){
response.config.ctrl.busy = false;
response.config.ctrl.data = response.data;
}
return response;
},
responseError : function(response){
// note: maybe use a different error message for different kinds of responses?
var error = response.status + " "+response.statusText+" - "+response.data;
if(response.config && response.config.ctrl){
response.config.ctrl.busy = false;
response.config.ctrl.error = error;
}
return $q.reject(error);
}
};
});
})