Reputation: 1976
I have a service making two consecutive calls to an API asynchronously.
I would like the app to wait for both to be resolved before proceeding and since one of calls may or may not be made, I believe $watch
is the way to go versus nested or chained callbacks.
var response_complete = {call1:false, call2:false};
$http.post("myapi.com/slug", data, header).then(function(res){
/* ... */
response_complete.call1 = true;
});
if(make_this_call==true){
$http.post("myapi.com/anotherslug", data, header).then(function(res){
/*...*/
response_complete.call2 = true;
});
} else response_complete.call2 = true;
$scope.$watch("response_complete",function(){
if(response_complete.call1==true && response_complete.call2==true){
console.log("DONE!");
}
});
So the idea is to create a global variable, and watch it as the two calls complete. The second call, which is conditional, immediately sets it's response variable to true
if it is not being made.
But the $watch
callback is only fired once and the condition within it (call1 & call2 == true) is never met.
Upvotes: 0
Views: 59
Reputation: 2300
your watch do not work as response complete is not a $scope
variable | property:
// replace this with $scope property declaration
//var response_complete = {call1:false, call2:false};
$scope.response_complete = {call1:false, call2:false};
then in your succeeding code use $scope.response_complete
to modify its value and so your $watch
will be triggered as $scope.response_complete
changed.
A better solution:
As others have specified it is better to use $broadcast
than $watch
, so instead watching the variable throw events instead and catch those event inside your $scope
.
$http.post("myapi.com/slug", data, header).then(function() {
// stuff
$scope.$broadcast("POST_SLUG_COMPLETE");
});
$http.post("myapi.com/anotherslug", data, header).then(function() {
// stuff
$scope.$broadcast("POST_ANOTHERSLUG_COMPLETE");
});
// then in your $scope
$scope.$on("POST_SLUG_COMPLETE", function () {
// stuff
});
$scope.$on("POST_ANOTHERSLUG_COMPLETE", function () {
// stuff
});
hope that helps
Upvotes: 1
Reputation: 850
If you need your "global" variable for the current scope, you can just do:
$scope.complete = false;
$http.post("myapi.com/slug", data, header).then(function(res) {
$http.post("myapi.com/anotherslug", data, header).then(function(res) {
$scope.complete = true;
console.log("DONE!");
});
});
You may also use $rootScope for a more "global" value. Other alternatives are $broadcast or a property inside a service.
But more important is to ensure how are you using the async calls. If you want both to be resolved put the second call inside the first. The sample provided by you wouldn't work because response_complete.call1 = true is inside an async thread and it is always false by the time you try to verify it
Upvotes: 0