3

I have a service method that looks like:

this.myServiceFunction = function(){
    var deferred = $q.defer();
    $http({
        method: 'GET',
        url: 'domain/myendpoint'
    })
        .success(function(data){
            deferred.resolve(data);
        })
        .error(function(data){
            deferred.reject(data);
        });
    return deferred.promise;
};

I use this method in my controller in the following fashion:

$scope.myControllerFunction = function(){
    myService.myServiceFunction().then(function(){
        // Do things when promise resolves
    });
};

I would like to cancel the HTTP call above in another function on command. I found this answer which allows you to cancel a HTTP request by calling the resolve() method on the object returned from $q.defer(). But in my codebase, this object is never made available in my controller.

myService.myServiceFunction() in the example above returns a promise object returned from $q.defer(). How do I cancel my HTTP request within the confines of what I have?

Community
  • 1
  • 1
Lloyd Banks
  • 35,740
  • 58
  • 156
  • 248

1 Answers1

2

The following answers the question, without the overhead in your original code.

this.myServiceFunction = function(){
  this.canceler = $q.defer();
  return $http({
    method: 'GET',
    url: 'domain/myendpoint',
    timeout: this.canceler.promise   
  });
};

this.cancelServiceFunction = function() {
  return this.canceler.resolve();
};

If however, you are required to use that pattern for some reason, you can use the following:

this.myServiceFunction = function(){
  this.canceler = $q.defer();
  this.deferred = $q.defer();

  $http({
    method: 'GET',
    url: 'domain/myendpoint',
    timeout: this.canceler.promise   
  })
  .success(function(data){
    deferred.resolve(data);
  })
  .error(function(data){
    deferred.reject(data);
  });

  return deferred.promise;
};

this.cancelServiceFunction = function() {
  return this.canceler.resolve();
};
Seth Flowers
  • 8,990
  • 2
  • 29
  • 42
  • This is the same answer provided in the link I referenced. This requires me to change the return object from `myServiceFunction()` which I do not want to do. It's a pattern that's prevalent throughout my codebase and changing it would require a lot of downstream changes in the controllers – Lloyd Banks Mar 20 '17 at 15:38
  • @LloydBanks It doesn't change the return object from `myServiceFunction()` at all (well, except that this will allow you to use the old `success` and `error` callbacks in your controllers if you wanted to). He just removes the redundant `var deferred = $q.defer();` and adds a canceller token. You can do exactly as you normally would in your controllers without changing a single character. – Nikolaj Dam Larsen Mar 20 '17 at 15:43
  • I was just trying to clean up your code, which only added overhead. I will update my answer to give you what you want. – Seth Flowers Mar 20 '17 at 15:55