I'm trying to update a progress bar with a sequential http request inside a foreach, this works, but it's not synchronous by on complete, progress bar is being sync'd by the http call, what am I doing wrong?
angular.forEach(queue, function (item) {
if (item.uid) {
d.item = item;
$http({
url: BASE_URL + 'upp',
method: 'post',
data: d
}).then(function(res){
x++;
update_progress((x/queue_count)*100);
});
}
});
I would like to call the update_progress function just when the http returns as finished (200 OK), so the progress bar shows the actual progress correctly. Thanks!
Edit:
I tried checking the response status, before calling the *update_progress* function and it still does not work as expected. I wasn't aware that 200 was dispatched before the request is completed :| By logic, the res obj shouldn't be the response of the http request? I mean, if it's 200 and not an error code, that shouldn't mean that the request was completed?
angular.forEach(queue, function (item) {
if (item.uid) {
d.item = item;
$http({
url: BASE_URL + 'upp',
method: 'post',
data: d
}).then(function(res){
if(res.status == 200) {
x++;
update_progress((x/queue_count)*100);
}
});
}
Reading more on promises atm to see if I can make it work as stated by @josh-strange
Edit 2:
So promises was the way to do it, all requests are sent sequentially so the progress bar works as expected, here's the code:
var promise = $q.all({});
// Had to init $q.all with an empty obj, 'cause null was trowing errors
angular.forEach(queue, function(item){
if (item.uid) {
promise = promise.then(function(){
d.item = item;
return $http({
url: BASE_URL + 'upp',
method: 'post',
data: d
}).then(function(res){
x++;
update_progress((x/queue_count)*100);
});
});
}
});
promise.then(function(){
end_js_update();
});
Thanks @josh-strange
Here is a working Plunker of a working example of sequential http requests. You could obviously package this up very nicely in a service but for your purposes I just put a simple example of it in a controller.
Here is the "meat" of the code:
var app = angular.module('testApp',[]);
app.controller('myController', function($scope, $http, $q){
$scope.responses = [];
$scope.doneLoading = false;
var urls = [
'http://httpbin.org/ip',
'http://httpbin.org/user-agent',
'http://httpbin.org/headers'
];
var promise = $q.all(null);
angular.forEach(urls, function(url){
promise = promise.then(function(){
return $http({
method: 'GET',
url:url
}).then(function(res){
$scope.responses.push(res.data);
});
});
});
promise.then(function(){
//This is run after all of your HTTP requests are done
$scope.doneLoading = true;
})
});
EDIT: As Mike P says below: This is an example of chaining promises see $q documentation.
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