Reputation: 3094
I have a factory which returns an object with several properties. But each property value is computed by ajax call and in some cases I do promise chaining in order to set a property value. Before I return the object how do i make sure all ajax calls are done such that property values are assigned
My factory looks something like this
app.factory('Resource', ['$http', '$q', function ($http, $q) {
var Resource = {
masterDB: null,
replicaDB: null,
replicaCluster: null,
masterForests: null,
forestHosts:{}
};
Resource.setMasterDB = function (dbname) {
console.log('inside setMasterDB', dbname);
this.masterDB = dbname;
};
Resource.getResources = function (dbname) {
var url = '/manage/v2/databases/'+ dbname + '?format=json';
$http.get(url).then(function (response) {
Resource.masterForests = getAttachedForests(response.data);
console.warn('Master Forests = ', Resource.masterForests);
return response;
}).then(function (response) {
Resource.replicaCluster = getReplicaClusters(response.data);
console.warn('Replica Cluster = ',Resource.replicaCluster);
}).then(function () {
console.log('final then', Resource.masterForests);
var reqs = function () {
var arr = [];
angular.forEach(Resource.masterForests, function(forestName){
arr.push($http.get('/manage/v2/forests/'+ forestName + '?format=json'));
});
return arr;
}.call();
console.log('reqs = ', reqs);
$q.all(reqs).then(function (results) {
console.warn(results);
angular.forEach(results, function(result){
console.log('HOST', getForestHost(result.data));
});
return results;
});
});
};
console.warn('RESOURCES: ', JSON.stringify(Resource));
return Resource;
}]);
Upvotes: 0
Views: 945
Reputation: 2379
We had scenario where the datas have to be updated from two different ajax responses, we have followed the below approach.
For Example:
function functionname()
{
var First_Response = $http.$get("/test1/test2/...");
var Second_Response = $http.$get("test3/test4/...");
return $q.all([First_Response,Second_Response]); // This function will return only when all the ajax responses are obtained.
}
In the below url: https://docs.angularjs.org/api/ng/service/$q
It is mentioned that $q.all will return result only when all the requests mentioned in the array gets the ajax response. We tried this approach and it worked for us. Hopefully it will give some pointers
Upvotes: 1
Reputation: 3094
Here's the working code
getResources: function (dbname) {
var url = '/manage/v2/databases/'+ dbname + '?format=json';
return $http.get(url).then(function (response) {
Resource.masterForests = getAttachedForests(response.data);
Resource.appservers = getAttachedAppServers(response.data);
Resource.replicaClusters = getReplicaClusters(response.data);
console.warn('Master Forests = ', Resource.masterForests);
return Resource.replicaClusters;
}).then(function(replicaClusters) {
var clusterArr = [];
angular.forEach(replicaClusters, function(cluster) {
clusterArr.push($http.get('/manage/v2/clusters/'+ cluster + '?format=json'));
});
return $q.all(clusterArr).then(function(results) {
angular.forEach(results, function(result) {
var cluster = result.data['foreign-cluster-default'].name;
var dbs = getReplicaDBs(result.data);
Resource.replicaDBs[cluster] = dbs;
});
});
}).then(function() {
var forestarr = [];
angular.forEach(Resource.masterForests, function(forestName){
forestarr.push($http.get('/manage/v2/forests/'+ forestName + '?format=json'));
});
return $q.all(forestarr).then(function (results) {
angular.forEach(results, function(result){
var host = getForestHost(result.data);
var forest = result.data['forest-default'].name;
Resource.forestHosts.push(host);
// group forest by hosts
groupForestsByHost(Resource, host, forest);
});
});
});
}
In controller
Resource.getResources($scope.db).then(function() {
$scope.masterForests = Resource.masterForests;
$scope.replicaClusters = Resource.replicaClusters;
$scope.forestHosts = Resource.forestHosts;
$scope.forestsOnHosts = Resource.forestsOnHosts;
$scope.replicaDBs = Resource.replicaDBs;
$scope.appservers = Resource.appservers;
}
Upvotes: 0