public
Last active

[AngularJS] Loading Indicator module that handles displaying/hiding an element while requests are being made to the server.

  • Download Gist
loadingindicator.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
/**
* Loading Indicator
*
* @author Maikel Daloo
* @date 12th March 2013
*
* Creates a new module and intercepts all ajax requests.
* Every time a request is sent, we display the loading message and increment
* the enable_counter variable. Then when requests complete (whether success or error)
* we increment the disable_counter variable and we only hide the loading message
* when the enable/disable counters are equal.
*
* @example
* All that is required to get this working is to inject this module into your main
* module. E.g.
* var app = angular.module('my-app', ['LoadingIndicator']);
* Then the script will look for the element specified in the LoadingIndicatorHandler object
* and show/hide it.
*/
var module = angular.module('LoadingIndicator', []);
 
module.config(['$httpProvider', function($httpProvider) {
var interceptor = ['$q', 'LoadingIndicatorHandler', function($q, LoadingIndicatorHandler) {
return function(promise) {
LoadingIndicatorHandler.enable();
return promise.then(
function( response ) {
LoadingIndicatorHandler.disable();
return response;
},
function( response ) {
LoadingIndicatorHandler.disable();
// Reject the reponse so that angular isn't waiting for a response.
return $q.reject( response );
}
);
};
}];
$httpProvider.responseInterceptors.push(interceptor);
}]);
 
/**
* LoadingIndicatorHandler object to show a loading animation while we load the next page or wait
* for a request to finish.
*/
module.factory('LoadingIndicatorHandler', function()
{
// The element we want to show/hide.
var $element = $('#loading-indicator');
return {
// Counters to keep track of how many requests are sent and to know
// when to hide the loading element.
enable_count: 0,
disable_count: 0,
/**
* Fade the blocker in to block the screen.
*
* @return {void}
*/
enable: function() {
this.enable_count++;
if ( $element.length ) $element.show();
},
/**
* Fade the blocker out to unblock the screen.
*
* @return {void}
*/
disable: function() {
this.disable_count++;
if ( this.enable_count == this.disable_count ) {
if ( $element.length ) $element.hide();
}
}
}
});

love this! thanks!

Adding something like that helped me:

var spinnerFunction = function (data, headersGetter) {
$('#loading-indicator').show();
return data;
};
$httpProvider.defaults.transformRequest.push(spinnerFunction);

Wouldn't the "Angular way" be to make the LoadingIndicatorHandler a directive?

Agree w/ Schlogen, referencing an ID is considered anti-Angular. Here's an example w/o using selectors:

https://github.com/MandarinConLaBarba/angular-examples/blob/master/loading-indicator/index.html

Also, I believe responseInterceptors are now deprecated.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.