Reputation: 6612
I have an asynchronous web service which will return status "pending" immediately until it returns either 200 or an error. This is my code so far:
$http.get('/myweb/services/callService').success(function(response, status, headers, config){
...handling success
}).error(function(err, status, headers, config){
//handling failure
});
//called just after $http.get
$scope.askProgress();
Where askProgress is:
$http.get('/myweb/services/progress').success(function(response, status, headers, config){
console.log(response);
$scope.reportProgress = response.description;
if(response.description < 100){//description is a 0-100 value indicating progress
...updating status...
$timeout(function() {$scope.askProgress();}, 1000); //calling again
}else{
$scope.reportProgressL = "Done!";
}
}).error(function(err, status, headers, config){
alert('Error: '+err+" "+status);
});
My problem is that the first call to askProgress is made before the service returns status "pending" leading to a non consistent progress value. I'd like for the askProgress function to be called just after the service gives me the first "pending"...is it possible?
Upvotes: 0
Views: 283
Reputation: 4862
Not sure I understand you problem fully but it sounds like you need to be calling your askProgress()
function after the first http request returns. If so, have you tried putting the call inside your then()
call?
$http
.get('/myweb/services/callService')
.then(function(response, status, headers, config){
return $scope.askProgress();
})
.then(function(progressResponse){
})
.catch(function(error){});
Update
I think you will need to register an $http
interceptor to track the state of your request.
Try this:
app.js
var app = angular.module('plunker', []);
app.factory('myHttpInterceptor', [ function() {
var pendingRequests = {};
return {
getPendingRequests: function(){
return pendingRequests;
},
request: function(request) {
console.log('*** request made @ %s ***', new Date());
pendingRequests[request.url] = true;
console.log('pendingRequests', pendingRequests);
console.log('**************************');
return request;
},
response: function(response) {
console.log('*** response received @ %s ***', new Date());
var url = response.config.url;
if(pendingRequests.hasOwnProperty(url)){
delete pendingRequests[url];
}
console.log('pendingRequests', pendingRequests);
console.log('**************************');
return response;
}
};
}]);
app.config(['$httpProvider', function($httpProvider) {
// register our factory as an http interceptor
// in the config phase
$httpProvider.interceptors.push('myHttpInterceptor');
}]);
app.controller('MainCtrl', function($scope, $http, $timeout, myHttpInterceptor) {
var targetUrl = 'big-data.json';
$scope.callService = function(){
console.log('*** call service ***');
return $http.get(targetUrl)
.then(function(){
console.log('********** done, success **********');
})
.catch(function(){
console.log('********** done, error **********');
});
}
$scope.askProgress = function(){
var pendingReqs = myHttpInterceptor.getPendingRequests();
// the request in this demo is very quick
// so I have had to change the time between checks
// you will probably want to change this for your
// own app
return $timeout(1)
.then(function(){
if(pendingReqs.hasOwnProperty(targetUrl)){
console.log('*** stil pending ***');
return $scope.askProgress();
}
console.log('*** no pending requests ***');
$timeout.cancel();
})
}
$scope.callService();
$scope.askProgress();
});
Upvotes: 1