Search code examples
angularjsangularjs-serviceangularjs-factory

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;

}]);

Solution

  • 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;
     }