A Way To Know When Angular $http Is "requesting"
Solution 1:
You can make use of $http.pendingRequests
array of config objects for currently pending requests. It is possible to use it that way:
$scope.isLoading = function () {
return$http.pendingRequests.length !== 0;
};
Solution 2:
None of the answers here really nailed it for me, and I shun using $http.pendingRequests
, so here's what I've done
My use case was that I had to show a simple "Loading.." message on the top of my viewport if I had any in-flight requests doing things on the server.
Inside .config
, I've registered a new Interceptor. and inside there I've added a simple counter that increments by 1 per request and decrements per response.
$httpProvider.interceptors.push([function () {
var pendingRequestsCounter = 0;
return {
request: function (request) {
pendingRequestsCounter++;
if (pendingRequestsCounter > 0) {
// we have some pending requests, so do something here
}
return request;
},
response: function (response) {
pendingRequestsCounter--;
if (pendingRequestsCounter === 0) {
// we have no pending requests, so do something else here
}
return response;
}
};
}]);
Solution 3:
this jsbin project takes @DmitryEvseev's answer to the next step. It provides finer control over which requests can be used to trigger "loading...".
Those requests with { showLoader: true }
are used to show the 'loading...' panel.
HTML
<divng-app="app"><divng-controller="spinnerController as vm"><divng-if="vm.isLoading()">Loading ...</div></div></div>
Javascript
angular
.module('app', [])
.config(config)
.factory('httpLoader', httpLoader)
.factory('httpLoaderInterceptor', httpLoaderInterceptor)
.controller('spinnerController', spinnerController);
functionconfig($httpProvider) {
//adding the default http status code handler
$httpProvider.interceptors.push('httpLoaderInterceptor');
}
functionhttpLoader() {
var pendingReqs = {};
var factory = {
addPendingReq: addPendingReq,
subtractPendingReq: subtractPendingReq,
getPendingReqs: getPendingReqs
};
return factory;
functionaddPendingReq(url) {
console.log('adding url', url);
pendingReqs[url] = true;
}
functionsubtractPendingReq(url) {
console.log('removing url', url);
delete pendingReqs[url];
}
functiongetPendingReqs() {
returnsizeOf(pendingReqs);
}
}
functionhttpLoaderInterceptor($q, httpLoader) {
var factory = {
request: request,
response: response,
responseError: responseError
};
return factory;
functionrequest(config) {
console.log('request', config.url);
if (config.showLoader) {
httpLoader.addPendingReq(config.url);
}
return config;
}
functionresponse(res) {
console.log('response', res.config.url);
if (res.config.showLoader) {
httpLoader.subtractPendingReq(res.config.url);
}
}
functionresponseError(res) {
console.log('responseError', res.config.url);
if (res.config.showLoader) {
httpLoader.subtractPendingReq(res.config.url);
}
return $q.reject(res);
}
}
functionspinnerController($http, httpLoader) {
var self = this;
self.isLoading = function() {
return httpLoader.getPendingReqs() > 0;
};
$http.get('http://stackoverflow.com/posts/34561385',{
showLoader: true
});
$http.get('http://www.amazon.com', {
showLoader: true
});
$http.get('http://www.yahoo.com',{
showLoader: true
});
$http.get('http://www.stackoverflow.com',{
showLoader: true
});
}
functionsizeOf(obj) {
var size = 0,
key;
for (key in obj) {
if (obj.hasOwnProperty(key)) {
size++;
}
}
return size;
}
Solution 4:
Try this directive: https://github.com/afeiship/angular-isloading
css:
body {
font-family: 'STHeiti', 'Microsoft YaHei', Helvetica, Arial, sans-serif;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0)
}
.loading-widget {
width: 100px;
height: 100px;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
position: absolute;
}
.loading-widget,
.loading-widget[data-visible] {
display: none;
}
.loading-widget[data-visible=true] {
display: block;
}
.loading-widgetimg {
width: 100%;
height: 100%;
}
html:
<div class="loading-widget"
isloading
loading="loading"
data-visible="{{loading}}"
>
<imgsrc="svg/default.svg"alt=""></div>
javascript:
angular.module('TestApp', ['nx.widget']);
angular.module('TestApp').
controller('MainCtrl', function ($http, $q, $rootScope) {
$rootScope.loading = false;
var s1 = $http.get('http://www.baidu.com');
var s2 = $http.get('http://www.sina.com');
var s3 = $http.get('http://www.163.com');
var s4 = $http.get('http://www.qq.com');
var s5 = $http.get('http://www.hao123.com');
//you need a VPN if you're a Chinese(Thanks to the GFW)var s6 = $http.get('https://www.google.com/');
$q.all([s1, s2, s3, s4, s5, s6]).then(function (responses) {
console.log(responses);
})
});
description:
- isloading
<!--1.attach the directive-->
- loading="loading"
<!--2.write the scope.loading to the app.$rootScope-->
- data-visible="{{loading}}"
<!--2.read loading props for CSS-->
Post a Comment for "A Way To Know When Angular $http Is "requesting""