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
    Commented Jul 5, 2017 at 9:16
  • \$\begingroup\$ @Tushar i guess you mean below 0 and yes you right, must make sure this doesn't happen \$\endgroup\$ Commented Jul 5, 2017 at 10:19
  • 2
    \$\begingroup\$ looks fine as long as both decrements are in a finally \$\endgroup\$
    – Jonah
    Commented Jul 5, 2017 at 14:18

3 Answers 3

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\$ Commented Jul 31, 2017 at 7:30
  • \$\begingroup\$ Are those requests are parllel or sequential? \$\endgroup\$
    – user59802
    Commented Jul 31, 2017 at 8:05
  • \$\begingroup\$ parallel, one can end before another \$\endgroup\$ Commented 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\$ Commented Oct 9, 2018 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\$ Commented 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\$ Commented 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
    Commented Oct 13, 2017 at 9:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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