Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cancelling ongoing Angular $http requests when there's a new request

Tags:

How does one cancel an ongoing Angular $http request when there's a new request?

I've got an Angular app with a view that updates live as the user types. Sometimes old requests complete after the latest request, meaning the view displays the wrong data. What's the most straightforward way to cancel the previous request when there's a new one?

Using Angular 1.5, for what it's worth.

<input ng-model = "query" ng-keyup = "search()"/>
{{results | json}}

// In the controller:
    $scope.search = function(){
        $http({
            method: "GET",
            url: "/endpoint.php"
            params: {
                query: $scope.query
            }
        }).then(function(response){
            $scope.results = response.data;
        })
    }

One solution I have tried:

// In the controller:
    var canceler = $q.resolve();    // New
    $scope.search = function(){
        canceler.resolve("Canceling old request");     // New
        $http({
            method: "GET",
            url: "/endpoint.php"
            params: {
                query: $scope.query
            },
            timeout: canceler.promise    // New
        }).then(function(response){
            $scope.results = response.data;
        })
    }

In this scenario, even though I'm calling canceler.resolve before the $http request, the request turns up as "failed".

Any insights?

edit: Solution found!

// In the controller:
    var canceler = $q.defer();

    $scope.search = function(){
        canceler.resolve("cancelled"); // Resolve the previous canceler
        canceler = $q.defer();        // Important: Create a new canceler! 
                                      // Otherwise all $http requests made will fail
        $http({
            method: "GET",
            url: "/endpoint.php"
            params: {
                query: $scope.query
            }
        }).then(function(response){
            $scope.results = response.data;
        })
    }
like image 935
caitlin Avatar asked Feb 13 '16 01:02

caitlin


People also ask

How to cancel api request in Angular?

Cancel a Request - Rangle.io : Angular Training. Cancelling an HTTP request is a common requirement. For example, you could have a queue of requests where a new request supersedes a pending request and that pending request needs to be cancelled. To cancel a request we call the unsubscribe function of its subscription.

How do I terminate HTTP request?

You can abort the current HTTP request using the abort() method, i.e., after invoking this method, on a particular request, execution of it will be aborted. If this method is invoked after one execution, responses of that execution will not be affected and the subsequent executions will be aborted.

How do you modify the $HTTP request default Behaviour?

To add or overwrite these defaults, simply add or remove a property from these configuration objects. To add headers for an HTTP method other than POST or PUT, simply add a new object with the lowercased HTTP method name as the key, e.g. $httpProvider. defaults.


1 Answers

When you start a new search, call the cancel() function. And you can use a resolved variable to make sure that you do not abort your $http call before it starts. Something like this:

var canceler = $q.defer();
var resolved = false;

var cancel = function() {
    canceler.resolve("http call aborted");
};

$scope.search = function() {
    if (resolved) {
        cancel();
    }

    canceler = $q.defer();
    resolved = true;

    $http({
        method: "GET",
        url: "/endpoint.php"
        params: {
            query: $scope.query
        }
        timeout: canceler.promise
    }).then(function(response) {
        $scope.results = response.data;
        resolved = false;
    })
}

Don't forget to inject $q in your controller/directive/service.

like image 70
6324 Avatar answered Oct 22 '22 14:10

6324