0

I have a controller that performs a http request.
This request can take anywhere between 2 seconds to 4 minutes to return some data .
I have added a button, that users should click to cancel the request if searches take too long to complete.

Controller:

$scope.search = function() {
    myFactory.getResults()
        .then(function(data) {
        // some logic
        }, function(error) {
        // some logic
    });
}

Service:

var myFactory = function($http, $q) {
    return {
        getResults: function(data) {
            var deffered = $q.dafer();
            var content = $http.get('someURL', {
                data: {},
                responseType: json
            )}

            deffered.resolve(content);
            returned deffered.promise;
        }
    }
}

Button click:

$scope.cancelGetResults = function() {

    // some code to cancel myFactory.getResults() promise

}

How can I implement a button click to cancel the myFactory.getResults() promise?

iHasCodeForU
  • 179
  • 11
Oam Psy
  • 8,555
  • 32
  • 93
  • 157
  • Do you need a **manual** cancelling, or something with a timeout fits your needs? – Mistalis Dec 13 '16 at 16:05
  • @Mistalis - manual, as users can either wait for the request to timeout, or click Cancel – Oam Psy Dec 13 '16 at 16:27
  • Possible duplicate of [How to cancel an $http request in AngularJS?](http://stackoverflow.com/questions/13928057/how-to-cancel-an-http-request-in-angularjs) – Liam Dec 14 '16 at 13:07

3 Answers3

1

The question uses deferred antipattern which usually should be avoided, but it fits the cancellation case:

getResults: function(data) {
    var deffered = $q.defer();

    $http.get('someURL', {
        data: {},
        responseType: json
    }).then(deffered.resolve, deferred.reject);

    deffered.promise.cancel = function () {
      deferred.reject('CANCELLED')
    };

    returned deffered.promise;
}
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • Thanks for this, however, i dont understand how $scope.cancelGetResults can be used with this?? – Oam Psy Dec 13 '16 at 16:30
  • 1
    Something like `$scope.resultsPromise = myFactory.getResults(...)` in `$scope.search` method. And `if ($scope.resultsPromise) $scope.resultsPromise.cancel()` in `$scope.cancelGetResults` method. – Estus Flask Dec 13 '16 at 16:38
  • Tried the above however i cant seem to get it to work, error is "Cannot read property 'cancel' of undefined" Please provide plunker. – Oam Psy Dec 13 '16 at 17:28
  • This totally depends on how you use it. Can you provide a plunker for how you're trying to do? – Estus Flask Dec 13 '16 at 17:34
  • Quick plunker here: http://plnkr.co/edit/D4Q8hMw37zd7gK5dmSaT?p=preview – Oam Psy Dec 13 '16 at 17:56
  • Something like this http://plnkr.co/edit/pBaeYbzcfbBovODLYKVy?p=info . There are syntax errors and typos here and there (**dafer**). – Estus Flask Dec 13 '16 at 18:37
  • Clicking Cancel throws "Cannot read property 'cancel' of undefined" – Oam Psy Dec 13 '16 at 18:40
  • Because there is an error that prevents `getData` from returning a promise. You need to fix your code first. Check the console for errors. You can also add additional check `if ($scope.resultsPromise) $scope.resultsPromise.cancel()` as it was suggested above. – Estus Flask Dec 13 '16 at 19:08
1

getResult is a service in which we are implementing cancellation.

getResult = function(){
var deferred = $q.defer();
$http.get(url).success(function(result){
   deffered.resolve(result);
}).error(function(){
deffered.reject('Error is occured!');
});
return deferred.promise;
};

where url variable is used in place of any Restful API url. You can use it with given code.

getResult().then(function (result) { console.log(result); };
Liam
  • 27,717
  • 28
  • 128
  • 190
0

You could use .resolve() method which should be available.

Pass the promise in the controller to the variable.

Create e.g. cancel method which takes the promise as an argument in you factory. Then call this method in the cancelGetResults() function in the controller.

In the cancel method you just call .resolve on the passed promise.

This should actually do.

https://www.bennadel.com/blog/2731-canceling-a-promise-in-angularjs.htm

Zdenek Hatak
  • 1,135
  • 14
  • 23