AlbertBrand / angular-cancel-on-navigate

MIT License
25 stars 12 forks source link

Code change request. #3

Open bjaraujo opened 8 years ago

bjaraujo commented 8 years ago

This modified source code solves 2 problems.

  1. If cancelOnRouteChange isn't defined, the call isn't cancelled. This is specially important when loading angular app directives. I have a redirect to login would cancel the loading of important app directives. The default behaviour should be not to cancel.
  2. Cancelled calls were hanging the angular-loading-bar. So loading would never finish.

I didn't create a PR because these changes are easy to implement. Source code below:

  angular
  .module('angularCancelOnNavigateModule', [])
  .config(function($httpProvider) {
    $httpProvider.interceptors.push('HttpRequestTimeoutInterceptor');
  })
  .run(function ($rootScope, HttpPendingRequestsService) {
    $rootScope.$on('$locationChangeSuccess', function (event, newUrl, oldUrl) {
      if (newUrl != oldUrl) {
        HttpPendingRequestsService.cancelAll();
      }
    });
  });

angular.module('angularCancelOnNavigateModule')
  .service('HttpPendingRequestsService', function ($q) {
    var cancelPromises = [];

    function newTimeout() {
      var cancelPromise = $q.defer();
      cancelPromises.push(cancelPromise);
      return cancelPromise.promise;
    }

    function cancelAll() {
      angular.forEach(cancelPromises, function (cancelPromise) {
        cancelPromise.promise.isGloballyCancelled = true;
        cancelPromise.resolve();
      });
      cancelPromises.length = 0;
    }

    return {
      newTimeout: newTimeout,
      cancelAll: cancelAll
    };
  });

angular.module('angularCancelOnNavigateModule')
  .factory('HttpRequestTimeoutInterceptor', function ($q, HttpPendingRequestsService) {
    return {
      request: function (config) {
        config = config || {};
        if (config.timeout === undefined && config.cancelOnRouteChange) {
          config.timeout = HttpPendingRequestsService.newTimeout();
        }
        return config;
      },

      responseError: function (response) {
        return $q.reject(response);
      }
    };
  });