You can apply the loader for every http request your app makes, keeping track of the number of active and resolved requests. So for every request xhrCreations
is added by 1
, and for every resolved xhrResolutions
is added by 1
.
So if the number of active requests are more than resolved, the service will be updated with a value of true
. And then when no requests are active the service will be updated with false
. Thus hiding your loader from the controller since the scope variable is set to false
.
core.factory('httpInterceptor', ['$q', 'globalStates', function ($q, globalStates) {
var xhrCreations = 0,
xhrResolutions = 0;
function isLoading() {
return xhrResolutions < xhrCreations;
}
return {
request: function (req) {
xhrCreations++;
globalStates.set('isRequestActive', isLoading());
return req;
},
requestError: function (err) {
xhrResolutions++;
globalStates.set('isRequestActive', isLoading());
return $q.reject(err);
},
response: function (res) {
xhrResolutions++;
globalStates.set('isRequestActive', isLoading());
return res;
},
responseError: function (err) {
xhrResolutions++;
globalStates.set('isRequestActive', isLoading());
return $q.reject(err);
}
};
}]);
Service:
core.service('globalStates', [function() {
var gs = this;
var states = {};
gs.set = function(k, v) {
states[k] = v;
};
gs.get = function(k) {
return k ? states[k] : states;
};
}]);
Then you can access the value in the service via a watcher from your core controller:
$scope.$watch(function() {
return globalStates.get();
}, function(states) {
$rootScope.showLoading = states.isLoading;
});