I have to execute three different $http
-calls sequentially which depend on each other. Until now my working solution is something like this:
$http.get(".../1/...").success(function() {
$http.get(".../2/...").success(function() {
$http.get(".../3/...").success(function() {
});
});
});
Now there is a certain change to be made: The first call should be skipped if a condition is true. I could do it like this:
if (skipCallOne) {
$http.get(".../2/...").success(function() {
$http.get(".../3/...").success(function() {
});
});
}
else {
$http.get(".../1/...").success(function() {
$http.get(".../2/...").success(function() {
$http.get(".../3/...").success(function() {
});
});
});
}
This obviously leads to massive code replication. I see that this could be reduced, if I used proper functions for the particular $http
-calls. But as I understand, a better solution would be to use the $http
-promises and properly chain them, like this:
$http.get(".../1/...").then(function() {
return $http.get(".../2/...");
}).then(function() {
return $http.get(".../3/...");
}).then(function() {
});
But now my question is, how can I conditionally skip the first call with the least code replication?
You can try this approach:
$q.when(skipCallOne || $http.get(".../1/..."))
.then(function() {
return $http.get(".../2/...");
}).then(function() {
return $http.get(".../3/...");
}).then(function() {
});
You can wrap the $http.get
calls in functions that test the condition and return the $http.get
promise if the conditions apply or a pre-resolved promise if not.
function callOne() {
if(condition) {
return $http.get(".../1/...");
} else {
var deferred = $q.defer();
deferred.resolve();
return deferred.promise;
}
}
callOne().then(function() {
return $http.get(".../2/...");
})
I like to be able to see stuff like this working, so I put this little controller together to demonstrate the promises resolving, with a conditional $http.get running first. I don't claim that this is elegant or as clever as the other answers, though I think it is quite similar to Cristian's solution.
Note: One thing that may make this difficult to understand is answers to this question often show chaining $http calls which are only executed, and for the sake of simplicity, the values those calls are returning are ignored and it may not be immediately clear how to break things apart to actually get at the values.
Demo
app.controller('MainCtrl', function($scope, $q, $http) {
$scope.x = true;
var firstHttp = function() {
var deferred = $q.defer()
if($scope.x) {
data = 'x was true'
deferred.resolve(data);
} else {
$http.get('test.json')
.then(function(data) {
$scope.data1 = data;
deferred.resolve(data);
})
}
return deferred.promise
}
$scope.myGetterFn = function() {
firstHttp()
.then(function(data)
{
data.data ? $scope.data1 = data : $scope.datax = data;
$http.get('test2.json')
.then(function(data2)
{
$scope.data2 = data2
$http.get('test3.json')
.then(function(data3)
{
$scope.data3 = data3
})
})
})
}
});
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