3

I need to append the necessary HMAC headers to a request. This should not be very difficult however I am starting to get frustrated. What is wrong with the following code. The actual http call I am doing works; I have run this call myself and it returns the necessary data. It does not work inside the interceptor.

I merely want to get the current implementation working before I add whitelist or blacklist and other customizable data for this interceptor. This is not a question about hmac however but with promises.

The error in this interceptor is with the entire promise line starting at $http(...). When i remove this block and use it as is (minus promise execution) it works fine. As soon as i uncomment the line it gets stuck in a loop and crashes chrome. Everywhere I have read says this is how it is done, but this clearly does not work.

function requestInterceptor(config){
  var $http = $injector.get('$http');
  var deferred = $q.defer();

  $http.get(hmacApiEndpoint, {cache: true}).then(function(data){
    console.log('HMAC - Success', data)
    deferred.resolve(config)
  }, function(config){
    console.log('HMAC - Error', config)
    deferred.resolve(config)
  })

  return deferred.promise;
}

return {
  request: requestInterceptor
};

Does this have something to do with the fact that angulars $http promise is a different implementation than that of '$q'?

2
  • 1
    will that $http call from request requestInterceptor will call requestInterceptor again? I doubt that it will call it recursively Commented May 4, 2015 at 19:07
  • 1
    @pankajparkar, I'm almost certain it will... so, to avoid an infinite loop, you should only apply the interceptor to urls other than hmacApiEndpoint. And $http returns the same promise + and additional .success/.error - so, it is the same or compatible Commented May 4, 2015 at 19:27

1 Answer 1

6

It doesn't look like you are actually amending the config with the newly obtainted HMAC.

Also, you'd need to protect against your requestInterceptor intercepting the call to obtain the HMAC, thus resulting in an infinite loop.

And lastly, you don't need deferred here - just return the promise produced by $http (or $http.then()):

function requestInterceptor(config){
  var $http = $injector.get('$http');

  // just return, if this is a call to get HMAC
  if (config.url === hmacApiEndpoint) return config;

  return $http.get(hmacApiEndpoint, {cache: true})
    .then(function(response){
      console.log('HMAC - Success', response.data)

      // not sure where the HMAC needs to go
      config.headers.Authorization = response.data;
      return config;
    })
    .catch(function(){
       return $q.reject("failed to obtain HMAC");
    });
}

return {
  request: requestInterceptor
};
Sign up to request clarification or add additional context in comments.

6 Comments

good solution, but could you explain me how will not call the interceptor for $http.get you are making for HMAC
@pankajparkar, It will get called, but it will skip the inner $http call to (again) get the HMAC
@pankajparkar, how so? The {cache: true} setting would make it retrieve the previous result without an Ajax request. maybe I'm missing something?
then that make sense..cool solution..as you gave everytime..you are great..:) +1 from me
That is fantastic! And exactly what is happening. I removed the hmac headers from this example because they are arbitrary. The infinite loop is what I overlooked. You are correct, the http interceptor is intercepting its own response and therefore never resolving. The cache true will in a very naive sense only allow one call, however the original call is being intercepted so the cacheFactory is not being populated with the values, ever. Thank you for this solution, everything you said makes perfect sense, I overlooked that recursive like loop.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.