I have 3 parallel promises or api requests once all teh three are done, I need to call another api request based on the second promise and then finally call .then( of $q.all
The inner $q.all is called in each iteration of the forEach loop, and gets as argument the array that is being populated during that forEach loop. This is obviously not right; it should be called only once, and its result should be the return value of the then callback.
So instead of this block:
$q.all(promise).then(() => {
    var nodePromise = [];
    angular.forEach(this.states, function(node) {
        var nodeId = node.Id;
        nodePromise.push(this.getNodeHealthSummary(nodeId).then(
            (resp) => {
                node.healthStatus = resp.data.operationalStatus;
            }));
        this.$q.all(nodePromise).then(() => {
            var index = this.states.indexOf(node);
            this.states.splice(index, 1, angular.copy(node));
        });
    },this);
}).then( ......
Do this:
$q.all(promise).then(() => {
    return $q.all(this.states.map((node, index) => {
        return this.getNodeHealthSummary(node.Id).then(resp => {
            node.healthStatus = resp.data.operationalStatus;
            this.states[index] = angular.copy(node);
        });
    }));
}).then( ......