How to block UI until all AJAX calls complete?

7,915 views
Skip to first unread message

alec...@gmail.com

unread,
Sep 9, 2013, 7:30:22 PM9/9/13
to ang...@googlegroups.com
Hello,

I need to prevent the user from using the UI until all background AJAX calls complete. So far I've been using jQuery's blockUI plugin to block before and unblock after ajax call. This feels wrong. What I would like to do is to unblock UI and allow the user to start using the page when there are no ajax calls in progress.

Any thoughts on this? I am sure a lot of people had to deal with this.

Thanks,

Alec

David Nelson

unread,
Sep 10, 2013, 1:48:20 AM9/10/13
to ang...@googlegroups.com
Hi Alec,

What I do is absolutely position a div on top of whatever content I want to hide, and in the div show the loading message and spinner.  I use an ng-show to show or hide the loading div based on a boolean that represents loading the data from the server.  Before the ajax call starts, I set loading to true.  If loading completes, I set loading to false.  If loading fails, I leave loading alone, but set another variable called errorOccured to true.  I then test for errorOccured in my div that is absolutely positioned with another ng-show, to show an error message, with a link to retry the ajax call.  Finally, before I make the ajax call, I also set the errorOccured to false.

I created a simple directive to encapsulate this functionality which I use all over my apps.  I'll open source it when I have some time.

Hope this helps,
David

Danny Eck

unread,
Sep 10, 2013, 1:55:26 AM9/10/13
to ang...@googlegroups.com
Don't know the details of your implementation, but sounds like something that resolves might be able help with. http://www.youtube.com/watch?v=Kr1qZ8Ik9G8&feature=share&list=PLP6DbQBkn9ymGQh2qpk9ImLHdSH5T7yw7

David Nelson

unread,
Sep 10, 2013, 1:58:34 AM9/10/13
to ang...@googlegroups.com
Hi Danny,

Great point!  I actually use resolve and the method I described together one scope above the resolved controller.  Works great!


David

On Monday, September 9, 2013 4:30:22 PM UTC-7, alec...@gmail.com wrote:

alec...@gmail.com

unread,
Sep 10, 2013, 11:19:29 AM9/10/13
to ang...@googlegroups.com
David and Danny, thank you for sharing the thoughts. I think resolve() is the way to go!

Thanks,

Alec

Chris Gross

unread,
Sep 10, 2013, 11:30:33 AM9/10/13
to ang...@googlegroups.com


--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.

Grant Rettke

unread,
Sep 11, 2013, 1:43:51 AM9/11/13
to ang...@googlegroups.com
We did the same thing. Eventually you will realize that users hate this approach, and relegate the spinner to a side-bar or somthing.


--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.



--
Grant Rettke | ACM, AMA, COG, IEEE
gre...@acm.org | http://www.wisdomandwonder.com/
“Wisdom begins in wonder.” --Socrates
((λ (x) (x x)) (λ (x) (x x)))
“Life has become immeasurably better since I have been forced to stop taking it seriously.” --Thompson

Marcus

unread,
Sep 11, 2013, 7:25:02 AM9/11/13
to ang...@googlegroups.com
Hi Chris,

Any chance you and Andy Joslin could merge your tools into a single directive solution ?

Your tools are so useful together, and it would become a universal solution for all our apps.

Thanks !

Marcus

Chris Gross

unread,
Sep 11, 2013, 9:59:32 AM9/11/13
to ang...@googlegroups.com
I haven't spoken with him but I'm ambivalent about it.  I like smaller libraries rather than monolithic ones.  Not sure there's really much to gain m by merging them...? I guess its one fewer script tags and one fewer module dependencies to list ...  It would help keep the versions in sync I guess.


Luke Kende

unread,
Sep 14, 2013, 3:14:18 AM9/14/13
to ang...@googlegroups.com
I wonder if these methods help on loading initial data for the app?  Blocking the UI during an ajax call is fairly simple from within a view once the app is loaded using the method described for setting a loading variable to true/false and binding it to ng-show/hide.  

The trouble I ran into is that I only need initial data retrieved via a $resource/$http ONCE before showing a view associated with a controller.  Resolve works, however, you don't need to reload this data each time that view is loaded.  Only the first time.  Even if you use a service and store the data the first time, making subsequent calls pull from local storage versus ajax call, there are some aspects you want for the controller to run and the resolve attribute forces the controller to always wait, making the view switching sluggish.

What I had to do was call my ajax methods in the run block and once all calls were done, set a value on rootScope that is watched in each controller associated with a view, like:

angular.module('app', [ ]
).
config( ... ).
run(function(myService, $rootScope){

   $rootScope.appInitialized = false

   var stuffLoaded = false, moreStuffLoaded = false;

   myService.getStuff().then(function(){
      stuffLoaded = true;
   })

   myService.getMoreStuff().then(function(){
      moreStuffLoaded = true;
   })
   
   $rootScope.$watch(function(){ return stuffLoaded && moreStuffLoaded }, function(allLoaded){
      $rootScope. appInitialized = true;
   })

})
. controller('MyViewCtrl',function($scope, myService){

    $scope.varsThatDontNeedToWait = { ... }
   
    $scope.$watch('appInitialized',function(ready){
       if (ready){ 
          startController();
       }
    })

    function startController(){
        $scope.varsAndMethodThatNeedInitialDataOrGetError =  myService.getAllStuff;
    }
})


Sorry if this digresses from the original topic a little but maybe it offers some insight, or maybe you guys have something to offer for this case.  Thanks

safiyu dheen

unread,
Nov 5, 2013, 6:31:17 AM11/5/13
to ang...@googlegroups.com
Hi folks, I have developed an angular blockui which is based on jim lavin's angularjs-spinner. It is easier to implement, simple and effective. Find detailed information at
https://github.com/safiyu/ng-blockUI

Adam Marr

unread,
Nov 13, 2013, 11:25:26 AM11/13/13
to ang...@googlegroups.com, gre...@acm.org
I agree that people don't want a "loading screen" blocking the UI every time a back-end call is made, but one of the things we did to get around this was to make the div opacity: 0, and fade it in with a .5 second delay to animation start using transition delay. That way the user cannot double submit, but the loading screen only starts to be visible if the call takes longer than 1/2 a second to return. Seems like a good trade off for our particular application.
Reply all
Reply to author
Forward
0 new messages