AlphaG33k
AlphaG33k

Reputation: 1678

Is there an AngularJS equivalent to $(document).ajaxSuccess()?

In AngularJS, I wish to create a catch-all-be-all ajax loader that does not need to be weaved into each controller in order to work. Traditionally, in jQuery I can do something like this:

(function globalAjaxLoader($){
 "use strict";
    var ajaxBoundElements = [$posts, $navigationLinks];
    ajaxBoundElements.forEach(function($elm){
       $elm.on('click', function(){
          $loader.show();
       });
    $(document).ajaxSuccess(function (event, XMLHttpRequest, ajaxOptions){
      $loader.hide();
    });
})(jQuery);

However, in AngularJS I am not seeing a global way of detecting ajaxCompletion (that is without going through the promise returned for each ajax call made through Angular individually)?

Thanks.

Upvotes: 0

Views: 150

Answers (2)

Tom
Tom

Reputation: 7740

Here I've put together a jsBin showing how to do this with an http interceptor.

I've used $rootScope.loadingCount so you can actually ng-show and ng-hide your based on that. Here is an example of the markup (you'd obviously use something a bit different:

<h1 ng-show="loadingCount > 0">Loading...</h1>

And here is the javascript:

angular
  .module('app', [])
  .config(httpInterceptorConfig)
  .factory('loadingDialogInterceptor', loadingDialogInterceptor);

// create your interceptor
loadingDialogInterceptor.$inject = ['$q', '$rootScope'];
function loadingDialogInterceptor($q, $rootScope) {
  $rootScope.loadingCount = 0;

  function showLoading() {
    $rootScope.loadingCount++;
  }

  function hideLoading() {
    if ($rootScope.loadingCount > 0) {
      $rootScope.loadingCount--;
    }
  }

  return {
    request: function (config) {
      showLoading();
      return config || $q.when(config);
    },
    response: function(response) {
      hideLoading();

      return response || $q.when(response);
    },
    responseError: function(response) {
      hideLoading();

      return $q.reject(response);
    }
  };
}

// actually register your interceptor
httpInterceptorConfig.$inject = ['$httpProvider'];
function httpInterceptorConfig($httpProvider) {
  $httpProvider.interceptors.push('loadingDialogInterceptor');
}

Upvotes: 2

Samir
Samir

Reputation: 374

You can achieve the same with interceptors.

myModule
.factory('httpResponseInterceptor', [
    '$q',
    function ($q) {
        return {
            request: function (request) {
                $loader.show();
                return request;
            },
            requestError: function () {
                $loader.hide();
            },
            response: function (response) {
                $loader.hide();
                return response || $q.when(response);
            },
            responseError: function (rejection) {
                $loader.hide();
                return $q.reject(rejection);
            }
        }
    }
])
.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.interceptors.push('httpResponseInterceptor');

    $httpProvider.defaults.transformRequest.push(function (data) {
        $loader.show();
        return data;
    });
})

Upvotes: 0

Related Questions