简体   繁体   中英

Reinvoke $http request in $http interceptor

So I am intercepting an angular $http request and response. Lets say that if I had a response error, I want to reinvoke my $http call. The issue is that I need to inject $http service into my interceptor and it creates a circular dependency. This is the simplified version of my code in coffeescript:

retryModule = angular.module('retry-call', [])

retryModule.factory 'RetryCall', ($q, $http)->
  # More object keys
  'responseError': (response)=>
    # Retry request if failed
    # I need a different way of invoking $http() to avoid circular dependency
    $http(response.config)
    $q.reject(response)

retryModule.config ['$httpProvider', ($httpProvider)->
    $httpProvider.interceptors.push('RetryCall');
]

Thanks

To avoid the circular dependency you could always just decorate the $http service to handle this functionality. Here is an example of a decorator.

You would basically do something like this pseudocode:

var old_post = $delegate.post;
$delegate.post = function(post_stuff) {
    var def = $q.defer();
    old_post(post_stuff).then(function(data) {
        if (data.error) {
            $delegate.post(post_stuff).then(function(data) {
                 def.resolve(data);
            }
        } else {
            def.resolve(data)
        }
    }, function(err_data) {
        // Also retry here
    });
};
return $delegate;

This basically wraps the original $http call in your retry functionality. The code is untested as it's just a basic idea of how to do it. Also you should be careful, since this could create an infinite loop.

Hope this helps!

After reviewing the Angular source code the better answer is such. $http method is accessible without dependency injection so the trick is to NOT INJECT $http and to simply use it. Like such:

Right Way

retryModule = angular.module('retry-call', [])

# Do not inject $http
retryModule.factory 'RetryCall', ($q)->
  # More object keys
  'responseError': (response)=>
    # Just use $http without injecting it
    $http(response.config)
    $q.reject(response)

retryModule.config ['$httpProvider', ($httpProvider)->
    $httpProvider.interceptors.push('RetryCall');
]

Wrong Way

# Do not do it this way.
retryModule.factory 'RetryCall', ($q,$http)->

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM