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;
})
}
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With