Reputation: 683
I have an input field. When there is a keyup on this field, I send a request with AJAX and $http service of angular. My problem is when another keyup event is triggered, I need to cancel all pending requests. I have seen a lot of answers, but I have not found a solution.
I tried two things :
A service that I call
App.factory('findArticlesService', function($http, $q) {
var self = this;
self.canceller = null;
return {
getArticles: function(route, formData) {
if (self.canceller) {
self.canceler.resolve("Other request is pending");
}
var deferred = $q.defer();
self.canceller = $q.defer();
$http.post(route, angular.toJson(formData), {timeout: self.canceller.promise}).success(function(data) {
deferred.resolve({data: data});
});
return deferred.promise;
}
};
});
App.controller('mainCtrl', ['$scope', '$http', '$q', 'findArticlesService', function($scope, $http, $q, findArticlesService) {
var res = findArticlesService.getArticles(route, $scope.formData);
console.log(res);
}]);
It doesn't work well.
And this :
var canceller = $q.defer();
canceller.resolve();
$http.post(route, angular.toJson($scope.formData), {timeout: canceller.promise}).then(function(data) {...});
This cancel all requests before they are sent.
Can you help me ?
Upvotes: 4
Views: 3355
Reputation: 3931
Since you are registering a factory and not a service you don't have to use 'this', your function is not going to be treated/instanciated as a constructor, with new keyword.
you need a service that maintains a canceller on every initiated request and cancels the previous request if another is sent
App.factory('findArticlesService', function($http, $q) {
var canceller;
return {
getArticles: function(route, formData) {
if (canceller) {
canceller.resolve("Other request is pending");
}
canceller = $q.defer();
return $http.post(route, angular.toJson(formData), {timeout: canceller.promise});
}
};
});
You don't even need an intermediary canceler, can use the same previous request as canceler
App.factory('findArticlesService', function($http) {
var canceler,
getArticles = function (route, formData) {
if (canceler) {
canceler.resolve('aborted');
}
canceler = $http.post(route, angular.toJson(formData), {timeout: canceler.promise});
return canceler;
};
return {
getArticles: getArticles
};
});
Upvotes: 2