following the DRY principal, i want to write a button directive which keeps button disabled for the duration of $http class.
I want to do this so as to forbid user from
I like @codef0rmer 's solution because it is centralized--that is there's no additional code needed for each HTTP request, and you just need to check the global progress
flag in your HTML. However, using transformResponse
to determine when the request has completed is unreliable because the server may not return anything; in that case the handler isn't called and progress
is never set back to false
. Also, as written that answer doesn't account for multiple simultaneous requests (progress
may return false
before all requests have completed).
I've come up a similar solution which uses interceptors to address these issues. You can put it in your Angular app's config function:
.config(function ($httpProvider) {
$httpProvider.interceptors.push(function($q, $rootScope) {
var numberOfHttpRequests = 0;
return {
request: function (config) {
numberOfHttpRequests += 1;
$rootScope.waitingForHttp = true;
return config;
},
requestError: function (error) {
numberOfHttpRequests -= 1;
$rootScope.waitingForHttp = (numberOfHttpRequests !== 0);
return $q.reject(error);
},
response: function (response) {
numberOfHttpRequests -= 1;
$rootScope.waitingForHttp = (numberOfHttpRequests !== 0);
return response;
},
responseError: function (error) {
numberOfHttpRequests -= 1;
$rootScope.waitingForHttp = (numberOfHttpRequests !== 0);
return $q.reject(error);
}
};
});
})
Now you can just use the waitingForHttp
to disable buttons (or show a "busy" page). Using interceptors gives an added bonus that now you can use the error functions to log all HTTP errors in one place if you want.