Show spinner GIF during an $http request in AngularJS? Show spinner GIF during an $http request in AngularJS? ajax ajax

Show spinner GIF during an $http request in AngularJS?


This really depends on your specific use case, but a simple way would follow a pattern like this:

.controller('MainCtrl', function ( $scope, myService ) {  $scope.loading = true;  myService.get().then( function ( response ) {    $scope.items = response.data;  }, function ( response ) {    // TODO: handle the error somehow  }).finally(function() {    // called no matter success or failure    $scope.loading = false;  });});

And then react to it in your template:

<div class="spinner" ng-show="loading"></div><div ng-repeat="item in items>{{item.name}}</div>


Here are the current past AngularJS incantations:

angular.module('SharedServices', [])    .config(function ($httpProvider) {        $httpProvider.responseInterceptors.push('myHttpInterceptor');        var spinnerFunction = function (data, headersGetter) {            // todo start the spinner here            //alert('start spinner');            $('#mydiv').show();            return data;        };        $httpProvider.defaults.transformRequest.push(spinnerFunction);    })// register the interceptor as a service, intercepts ALL angular ajax http calls    .factory('myHttpInterceptor', function ($q, $window) {        return function (promise) {            return promise.then(function (response) {                // do something on success                // todo hide the spinner                //alert('stop spinner');                $('#mydiv').hide();                return response;            }, function (response) {                // do something on error                // todo hide the spinner                //alert('stop spinner');                $('#mydiv').hide();                return $q.reject(response);            });        };    });//regular angular initialization continued below....angular.module('myApp', [ 'myApp.directives', 'SharedServices']).//.......

Here is the rest of it (HTML / CSS)....using

$('#mydiv').show(); $('#mydiv').hide(); 

to toggle it. NOTE: the above is used in the angular module at beginning of post

#mydiv {      position:absolute;    top:0;    left:0;    width:100%;    height:100%;    z-index:1000;    background-color:grey;    opacity: .8; }.ajax-loader {    position: absolute;    left: 50%;    top: 50%;    margin-left: -32px; /* -1 * image width / 2 */    margin-top: -32px;  /* -1 * image height / 2 */    display: block;     }<div id="mydiv">    <img src="lib/jQuery/images/ajax-loader.gif" class="ajax-loader"/></div>


Here's a version using a directive and ng-hide.

This will show the loader during all calls via angular's $http service.

In the template:

<div class="loader" data-loading></div>

directive:

angular.module('app')  .directive('loading', ['$http', function ($http) {    return {      restrict: 'A',      link: function (scope, element, attrs) {        scope.isLoading = function () {          return $http.pendingRequests.length > 0;        };        scope.$watch(scope.isLoading, function (value) {          if (value) {            element.removeClass('ng-hide');          } else {            element.addClass('ng-hide');          }        });      }    };}]);

by using the ng-hide class on the element, you can avoid jquery.


Customize: add an interceptor

If you create a loading-interceptor, you can show/hide the loader based on a condition.

directive:

var loadingDirective = function ($rootScope) {  return function ($scope, element, attrs) {      $scope.$on("loader_show", function () {          return element.removeClass('ng-hide');      });      return $scope.$on("loader_hide", function () {          return element.addClass('ng-hide');      });  };};

interceptor:

  • for example: don't show spinner when response.background === true;
  • Intercept request and/or response to set $rootScope.$broadcast("loader_show"); or $rootScope.$broadcast("loader_hide");

more info on writing an interceptor