3
\$\begingroup\$

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?

\$\endgroup\$
3
  • \$\begingroup\$ If there is no case where counter never reaches 0, then it's OK to use counters. \$\endgroup\$ – Tushar Jul 5 '17 at 9:16
  • \$\begingroup\$ @Tushar i guess you mean below 0 and yes you right, must make sure this doesn't happen \$\endgroup\$ – Ziv Weissman Jul 5 '17 at 10:19
  • 2
    \$\begingroup\$ looks fine as long as both decrements are in a finally \$\endgroup\$ – Jonah Jul 5 '17 at 14:18
1
\$\begingroup\$
  1. 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.
  2. 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.

\$\endgroup\$
0
\$\begingroup\$

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');
}]);
\$\endgroup\$
4
  • \$\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 Jul 31 '17 at 7:30
  • \$\begingroup\$ Are those requests are parllel or sequential? \$\endgroup\$ – user59802 Jul 31 '17 at 8:05
  • \$\begingroup\$ parallel, one can end before another \$\endgroup\$ – Ziv Weissman Jul 31 '17 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\$ – Bogdan Mart Oct 9 '18 at 0:47
-1
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\begingroup\$ And I would i know all request finish? I have to iterate the array containing these couple all the time? \$\endgroup\$ – Ziv Weissman Aug 30 '17 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 Aug 30 '17 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 Oct 13 '17 at 9:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.