9

I'm calling 4 to 10 $http get calls in parallel. But after user search action I need display to same view but with different result. I populate set of data and new $http query calls. But the previous $http invocations(promises) are still populating or in action, effecting $scope.

My possible dirty solution is ..

Using multi-app(multimodule) page which can have dynamic regions controlled by a dynamic app. On user events remove the element which correspond to the event. Example, search result, if I want to display results from different sources using different $http calls. If user searches with new keyword , I'm going to remove result ng-app element and bootstrap new element.

Raghu
  • 722
  • 3
  • 8
  • 19

1 Answers1

26

You should use version 1.1.5, which has the ability to cancel $http requests:

https://github.com/angular/angular.js/blob/master/CHANGELOG.md

// set up a dummy canceler
var canceler = $q.defer();

// use it as a timeout canceler for the request
$http({method: 'GET', url: '/some', timeout: canceler.promise}).success(
    function (data) { alert("this won't be displayed on cancel"); }
).error(
    function (data) { alert("this will be displayed on cancel"); }
)

// now, cancel it (before it may come back with data)
$rootScope.$apply(function() {
    canceler.resolve();
});

you can use the same canceler for all the requests, and resolve it just before starting the new set.

rewritten
  • 16,280
  • 2
  • 47
  • 50
  • Me too - link for 1.1.5 CHANGELOG is https://github.com/angular/angular.js/commit/5cc9837d931dfb2d374bef24688888e0c52c75d1 – Phantomwhale Nov 12 '13 at 22:35
  • Is there a reusable pattern for this? I'd like to cancel the processing that happens after the result has been fetched as well. – user239558 Feb 19 '14 at 20:54
  • I don't think so, the $http calls are asynchronous IO, so the event loop keeps spinning. If you are able to wrap your postprocessing code in some asynchronous "thing" that spawns several event ticks, then you may check at each tick if the canceler has cancelled. – rewritten Feb 20 '14 at 20:36
  • So we have to back and add this canceler promise to *each* request? Seems like a good fix if you've only got one or two promises going on, but it's not really scalable. – Doug Molineux Nov 11 '14 at 18:05
  • 1
    You can globally decorate `$http` and add always a canceller. See this gist for an example: https://gist.github.com/rewritten/7305c5e98fa6cd3790da – rewritten Nov 11 '14 at 20:45
  • 1
    @rewritten wouldn't this fail as soon as you had more than one concurrent request? you set `canceller` at the base of the decorator, but `$http` is a service and is only created once. This would indicate that one `canceller` is visible to **all** places that `$http` is accessed from - cancelling one request would cancel them all – Dan Mar 11 '15 at 13:43
  • @DanPantry +1 The proposal for global canceller is there because of the previous comment, I absolutely prefer adding the canceller on demand. – rewritten Mar 11 '15 at 22:34