0

I've tried to find the answer to this and have started reading about promises / deferred, but when kicked off from somewhere else I don't know how to approach this.

    angular.module('myapp.utilities').factory('codetabelService', ['Restangular', function(Restangular) {
    var initialized = false;
    var listtopopulate1 = [];
    var listtopopulate2 = [];

    var update = function() {
        Restangular.all('codeTabel').getList()
            .then(function(codetabellen) {
                codetabellen.forEach(function(entry) {
                    //do some processing on return values 
                    listtopopulate1.push(entry);
                    listtopopulate2.push(entry);
                });
                initialized=true;
            });
    };

    return {
        initialize: function() {
            if (!initialized) {
                update();
            }
        },
        getListValuesType1: function() {
            //How do I wait here for initialized to become true?
            return listtopopulate1;
        },
        getListValuesType2: function() {
            //How do I wait here for initialized to become true?
            return listtopopulate2;
        }
    };
}]);

So what I'm trying to do is cache some values when my single page app starts. On my root controller I call the initialize method which starts the async call to the backend. When my views are being loaded and the controller sets the scope values to the result of getListValuesType1() the asynch call is sometimes not yet complete.

Because the async load was not triggered by the controller that called the method getListValuesType1() I'm not sure if promises will work here (I admit, I'm still new to this)

I found out you can put a timer on it, but this didn't seem right. It just feels there's a better solution out there.

Community
  • 1
  • 1
Sjors Miltenburg
  • 2,540
  • 4
  • 33
  • 60

2 Answers2

1

Yes you can effectively use promise and promise caching to do this, one way you can achieve this by doing:-

angular.module('myapp.utilities').factory('codetabelService', ['Restangular', '$q', function(Restangular, $q) {

    var initialized;//Use this to cache the promise
    var listtopopulate1 = [];
    var listtopopulate2 = [];

    var _initialize = function() {
       //If already initialized just return it which is nothing but the promise. This will make sure initialization call is not made
       return initialized || (initialized= Restangular.all('codeTabel').getList()
            .then(function(codetabellen) {
                codetabellen.forEach(function(entry) {
                   listtopopulate1.push(entry);
                   listtopopulate2.push(entry);
                });
              //Note- You could even return the data here
            }, function(){
                //Just clean up incase call is a failure.
                initialized = null;
                //Just reject with something if you want to:-
                //return $q.reject("SomeError")
            }));
    };

    return {
        initialize: function() {
            return _initialize(); //Just return promise incase you want to do somthing after initialization
        },
        getListValuesType1: function() {
         return _initialize().then(function(){  //return promise with a chain that resolves to the list
            return listtopopulate1;
         });
        },
        getListValuesType2: function() {
         return _initialize().then(function(){ //return promise with a chain that resolves to the list
            return listtopopulate2;
         });
        }
    };
}]);

And while using it, you could do:-

codetabelService.getListValuesType1().then(function(list){
      $scope.list1 = list;
});

With this you can even get rid of the initialize call from the contract and make the ajax call only during the first usage of getListX methods.

PSL
  • 123,204
  • 21
  • 253
  • 243
0

promises will work for this. You may need to refactor some things though.

angular.module('myapp.utilities').factory('codetabelService', ['Restangular', function(Restangular) {
    var initialized = false;
    var listtopopulate1 = [];
    var listtopopulate2 = [];

    var update = function() {
        return Restangular.all('codeTabel').getList()
            .then(function(codetabellen) {
                codetabellen.forEach(function(entry) {
                    //do some processing on return values 
                    listtopopulate1.push(entry);
                    listtopopulate2.push(entry);
                });
                initialized=true;
            });
    };

    return {
        initialize: function() {
            if (!initialized) {
                this.updatePromise = update();
            }
        },
        getListValuesType1: function() {
            //How do I wait here for initialized to become true?
            return this.updatePromise.then(function() {
              // you'll want to refactor the callee to handle a promise here
              return listtopopulate1;              
            });
        },
        getListValuesType2: function() {
            return this.updatePromise.then(function(){
              // you'll want to refactor the callee to handle a promise here
              //How do I wait here for initialized to become true?
              return listtopopulate2;
            });
            //How do I wait here for initialized to become true?

        }
    };
}]);
Evil Buck
  • 1,068
  • 7
  • 20