I was using a Boolean var for indication of loading so my code looked like this: (this example is in angularjs but i think it can be relevant for any ajax call handlers)
//HTML:
<div ng-show="$scope.isLoading">...LOADING...</div>
//JS:
//Init
$scope.isLoading = false;
//Executing http request:
$scope.isLoading = true;
mainService.post(alteredItems).then(function (response) {
init();
}).catch(function (err) {
$scope.callBack(err);
}).finally(function () {
$scope.isLoading = false;
});
function init() {
$scope.isLoading = true; //another loading
mainService.get().then(function (response) {
if (response) {
}
$scope.isLoading = false;
});
}
The problem I had was that if 1 ajax method will complete before the other one so the "isLoading" will be false, and the loader will not be displayed although the request has not yet ended.
I converted the $scope.isLoading to int. So now code looks like this:
//Init
$scope.isLoading = 0;
//Start any ajax call
$scope.isLoading++;
//Finish
$scope.isLoading--;
Which works great, also no need to change the html because of the casting. I can't find a drawback in this approach and it seems better than the Boolean option.
What do you think?
3 Answers 3
- You SHOULD consider migrating to Angular (aka Angular2, aka Angular5) from ANgularJS (version 1), as it's not developing and soon won't be supported anymore.
- I guess nested promises would be much useful here (more details below).
Rewrite init() as follow
function init() {
return mainService.get().then(function (response) {
if (response) {
}
$scope.isLoading = false;
});
}
And in main block instead of
mainService.post(alteredItems).then(function (response) {
init();
})
Write:
mainService.post(alteredItems).then(function (response) {
return init();
})
In this case your finally would be called AFTER bot async calls completed.
P.S. Consider using library cg-buisy https://github.com/cgross/angular-busy It automates displaying of loading indicator and accepts promises. Used it a lot in production.
IMHO you can go with angularjs http request interceptor where you can get hold of the each request and response pipeline and show or hide the loader accordingly.,
module.factory('timestampMarker', [function() {
var requestInterceptor = {
request: function(config) {
$("#loaderDiv").show();
return config;
},
response: function(response) {
$("#loaderDiv").hide();
return response;
}
};
return requestInterceptor;
}]);
module.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('requestInterceptor');
}]);
-
\$\begingroup\$ But what happens if I have more than 1 request? When the first will end, but other still loads and loader will not be visible \$\endgroup\$Ziv Weissman– Ziv Weissman2017年07月31日 07:30:08 +00:00Commented Jul 31, 2017 at 7:30
-
\$\begingroup\$ Are those requests are parllel or sequential? \$\endgroup\$user59802– user598022017年07月31日 08:05:56 +00:00Commented Jul 31, 2017 at 8:05
-
\$\begingroup\$ parallel, one can end before another \$\endgroup\$Ziv Weissman– Ziv Weissman2017年07月31日 16:38:00 +00:00Commented Jul 31, 2017 at 16:38
-
\$\begingroup\$ This won;t work well if user have more than one component. Evolution of this solution could be used to display application wide loading panel on top of page, but OP is trying to hid part of screen, while loading, as I guess. Additionally it don't mitigate issue with mutiple requests, counter approach should be used, I guess. And JQuery, it's ugly...perhaps should change variable in $rootScope then? \$\endgroup\$Bohdan Mart– Bohdan Mart2018年10月09日 00:47:20 +00:00Commented Oct 9, 2018 at 0:47
Store a couple : function name + boolean so you can even provide information on which request is actually processing on a multi request process.
The benefit of this will be to Identify which one of the request is upon a time slow or not returning result.
Ex:
{[ req1:0, req2:1 req3:1 ]}
You'll know that req1 hasn't returned any result yet. With that simple int counter you loose that information, and won't be able to debug easily.
-
\$\begingroup\$ And I would i know all request finish? I have to iterate the array containing these couple all the time? \$\endgroup\$Ziv Weissman– Ziv Weissman2017年08月30日 11:47:15 +00:00Commented Aug 30, 2017 at 11:47
-
\$\begingroup\$ Welcome to Code Review! You have presented an alternative solution, but haven't reviewed the code. Please edit it to explain your reasoning (how your solution works and how it improves upon the original) so that everyone can learn from your thought process. \$\endgroup\$Toby Speight– Toby Speight2017年08月30日 12:04:13 +00:00Commented Aug 30, 2017 at 12:04
-
\$\begingroup\$ @ZivWeissman Well yeah. Not that long processing time though. Depends on how many request you have in that list.. I don't get why the -1 ... \$\endgroup\$Radium– Radium2017年10月13日 09:00:31 +00:00Commented Oct 13, 2017 at 9:00
0
, then it's OK to use counters. \$\endgroup\$