Sudhakar
Sudhakar

Reputation: 3094

how to return a factory object after all ajax calls are done

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

Answers (2)

NP Compete
NP Compete

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

Sudhakar
Sudhakar

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

Related Questions