javascript - How to abort/cancel promise for first call during 2 consecutive angular service calls? -
when 2 consecutive service calls made through $http angular service on dropdown item selection , assume first call took time return , second call return before first call resolve shows data of first call second item selection.
so there way abort first promise if service call made again before first call resolves.
for demo purpose created sample plunkar has dropdown few items added explicit condition on selection of first item took little longer time other items. select first item , select second item reproduce scenario, check favorite books display on screen.
any appreciated!
service code:
app.factory('bookservice', function($http, $q, $timeout) { return { getbook: function(id) { var promise = $q.defer(); var timeoutspan = id == 1 ? 3000 : 500; $http.get("favouritebooks.json").success(function(data) { $timeout(function() { promise.resolve(data.filter(function(obj) { return obj.id == id })); }, timeoutspan); }).error(function(msg) { promise.reject(msg); }) return promise.promise; } } });
i found 2 ways handle scenario -
case 1: create global $q deffer object @ service level , check whether object has value/or not before making call $http request. if deffer object has value resolved explicitly. plunkar code - code snippet
service code:
app.factory('bookservice', function($http, $q, $timeout, bookconstants) { var service = {}; service.mypromise = null; service.getbook = function(id) { if (service.mypromise) { service.mypromise.resolve(bookconstants.explicit_cancel); service.mypromise = null; } service.mypromise = $q.defer(); var timeoutspan = id == 1 ? 3000 : 500; $http.get("favouritebooks.json").success(function(data) { $timeout(function() { if (service.mypromise) { service.mypromise.resolve(data.filter(function(obj) { service.mypromise = null; return obj.id == id })) } }, timeoutspan); }).error(function(msg) { service.mypromise.reject(msg); }) return service.mypromise.promise; } return service; });
case 2: return $q deffer object service response , maintain @ controller level. , in case of consecutive service call first check , explicitly resolve first service call , proceed other service call. plunkar code - code snippet
sample code:
$scope.getselectedvalue = function() { var id = $scope.selitem.id $scope.cancel(); var bookpromise = bookservice.getbook(id); $scope.requests.push(bookpromise); bookpromise.promise.then(getbooksuccess) .catch(errorcallback) .finally(getbookcomplete); } function getbooksuccess(favouritebooks) { if (favouritebooks == 'user cancelled') { return; } var books = ''; angular.foreach(favouritebooks, function(book) { books += book.bookname + ' ' }); $scope.selectedvalues = 'name: ' + $scope.selitem.name + ' id: ' + $scope.selitem.id + ' favourite book(s): ' + books; } function errorcallback(errormsg) { console.log('error message: ' + errormsg); } function getbookcomplete() { console.log('getbook has completed!'); } $scope.cancel = function() { if ($scope.requests) { angular.foreach($scope.requests, function(request) { request.resolve('user cancelled'); clearrequest(request); }) } }; var clearrequest = function(request) { $scope.requests.splice($scope.requests.indexof(request), 1); }; }]); app.factory('bookservice', function($http, $q, $timeout) { var service = {}; service.getbook = function(id) { var promise = $q.defer(); var timeoutspan = id == 1 ? 3000 : 500; $http.get("favouritebooks.json").success(function(data) { $timeout(function() { promise.resolve(data.filter(function(obj) { return obj.id == id })) }, timeoutspan); }).error(function(msg) { promise.reject(msg); }) return promise; } return service; });
Comments
Post a Comment