0

I'm just testing the timeout functionality with Angular's $http module, however it keeps returning undefined as the response

It's fine if set up just like this, but if I tack on .error(function) instead of .then(function), to the $http call, it throws an error trying to grab the data field from an undefined object

var timeout = $q.defer();

var config = {
        url: 'http://192.168.1.65:3000',
        timeout: timeout.promise,
        method: 'POST'
    };

    $http(config).then(function(res) {
        // This is always undefined when timeout occurs
        console.log(res);
    });

    $timeout(function() {
        console.log('resolving the promise to abort the http call. This works fine');
        timeout.resolve();
    }, 1000);

Any ideas what I'm doing wrong?

5
  • You are not passing a value to your resolve call. Commented May 21, 2015 at 20:20
  • I don't believe thats the issue, I just tried as a sanity check and it didn't change anything...according to this other answer this should be all you need Commented May 21, 2015 at 20:25
  • Are you wanting to timeout your request or cancel it? I had to use something similar to this in my place of work and I don't think timeout accepts a promise. If you're looking to cancel your request, set cancellationToken to a promise. What other answer did you use? Commented May 21, 2015 at 20:27
  • @gfunk, when the request times out, it is a rejected promise - so you need .catch Commented May 21, 2015 at 20:29
  • oh sorry...this was the answer stackoverflow.com/a/21916315/3325262 Commented May 21, 2015 at 20:44

1 Answer 1

3

When $http times-out, it returns a rejected promise that you can handle with .catch:

$http(config)
  .then(function(response){
  })
  .catch(function(error){
     // will fire when timed out
  })

Demo

Off-topic: it's actually simpler to just use the promise generated by $timeout, without the need for $q.defer:

var timeout = $timeout(angular.noop, 1000);
$http.get(url, {timeout: timeout})
     .then(...)
     .catch(...)

EDIT:

In case there is an interceptor, then the timeout would result in responseError, and if defined, that interceptor essentially "handles" the error so it no longer becomes a rejected promise and the result is routed to .then - and if you do not return anything from the responseError function, the data passed to the .then handler is undefined. If you want to keep the rejection, you can do:

// inside http inteceptor
responseError: function(rejection){

  if (rejection.status === 0){ // if timeout
    return $q.reject({reason: "timeout"});
  }
  // ...
}
Sign up to request clarification or add additional context in comments.

4 Comments

If this is true then why is his console.log printing undefined? :s
@DanPantry, if it's implemented as he states in the question, then it doesn't get there. Maybe something else is printing "undefined"
@NewDev you're right, there was an interceptor in the code that was catching the error and then returning undefined
@gfunk, it is quite an essential data point to the question :)

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.