I have a rather complicated set of API calls to make and I'm attempting to do it as elegantly and performant as possible. I understand how to use the promise api of the $http service to chain requests, and how to use the $q service to make requests in parallel. But for this specific API workflow I need to do both.
Here is an example of the high-level API flow:
- /dog/<dog_id>- /breed/<breed_id>- /food/<food_id>
 
 
- /cat/<cat_id>
- /turkey/<turkey_id>
- /fish/<fish_id>
The first tier of requests all have known ids. However the <breed_id> required to make the /breed call must be parsed from the /dog response, and the <food_id> required to make the /food call must be parsed from the /breed response. So /dog, /breed, and /food all need to be chained. However /cat, /turkey, and /fish can be made in parallel with the entire /dog chain.
What I've got now (and it is working fine) are two separate sets of requests. How do I improve on this flow? Is there a way to combine the two stacks in a way that results in a single promise execution of .then()?
var dogId = '472053',
    catId = '840385',
    turkeyId = '240987',
    fishId = '510412';
var myData = {};
var firstSetComplete = false,
    secondSetComplete = false,
    returnData = function() {
        if (firstSetComplete && secondSetComplete) {
            console.log("myData.dog", myData.dog);
            console.log("myData.dog.breed", myData.dog.breed);
            console.log("myData.dog.food", myData.dog.food);
            console.log("myData.cat", myData.cat);
            console.log("myData.turkey", myData.turkey);
            console.log("myData.fish", myData.fish);
        }
    };
// first call set
$http.get('http://example.com/dog/' + dogId)
.then(function(response) {
    myData.dog = response.data;
    return $http.get('http://example.com/breed/' + response.data.breed_id);
})
.then(function(response) {
    myData.dog.breed = response.data;
    return $http.get('http://example.com/food/' + response.data.food_id);
})
.then(function(response) {
    myData.dog.food = response.data;
    firstSetComplete = true;
    returnData();
});
// second call set
$q.all([
    $http.get('http://example.com/cat/' + catId),
    $http.get('http://example.com/turkey/' + turkeyId),
    $http.get('http://example.com/fish/' + fishId)
])
.then(function(responses) {
    myData.cat = responses[0].data;
    myData.turkey = responses[1].data;
    myData.fish = responses[2].data;
    secondSetComplete = true;
    returnData();
});
 
     
    