Radu Andrei
Radu Andrei

Reputation: 1073

$rootScope property value undefined in service

I have a table in a database that i need to access before anything else goes on in my website. The values that i get, i'll be using all throughout different controllers, directives, services etc. I thought the best place to store those values would be in the $rootScope so to that end, i did the following:

obApp.run(function($rootScope, ngProgress, $timeout) {
  $.post('phpProcessingPage', function(data){
   $rootScope.domains = JSON.parse(data); //this "domains" property is what i'm interested in
  })
})

I get the domains back without a hitch so all is good. The problem is, when i inject the $rootScope into a service:

obApp.factory('requestOrigin', ['$rootScope', function($rootScope){
   console.log($rootScope.domains); //this is undefined at this point
   return $rootScope.domains; //returns undefined
}]);

It's to be expected that there would be nothing there as the response would come after the service code executed.

The problem is, i use that factory code in multiple controllers and i don't know how to delay it's execution so that it waits until i get data back from my ajax call.

I've tried doing a broadcast but there's no way (that i know of) to delay the retun of the factory even if at some point i do get the results back. How would i go about this problem that i have?

ANSWER:

Scrap the usage of $rootScope for this. The controller where i use the returned results from the service looks like this:

oApp.controller(['serviceName', function(serviceName){
    serviceName.then(function(response){
      //here i have the data from the ajax call, the service made
      //other things to do
    });
}]);

And the service looks like this:

obApp.factory(['serviceName','$http', function(serviceName, $http){
    return $http.post('phpProcessingPage.php', {cache: true});
}]);

Upvotes: 0

Views: 1638

Answers (2)

Omri Aharon
Omri Aharon

Reputation: 17064

I'd say you need to redesign this little thing using promises.

Use a service to store and return this data, and from your controllers/directive/etc, you can do the following:

DomainService.getDomains().then(function () {
    // Do whatever you need, here you'll have the data
});

Now the service should return the data, or fetch it from the server when it doesn't have it when the app is running for the first time:

// Domain service
var domains;

var getDomains = function () {
    // using angular's $q service
    var deferred = $q.defer();

    if (domains) {
        // returns the data without going to the server
        deferred.resolve(domains);
    }  
    else {
        // fetches the data the first time, also notice angular's $http service
        $http.post('phpProcessingPage', data).then(function(response)
            domains = response;
            deferred.resolve(domains);
        });
    }

    return deferred.promise;
}

Upvotes: 2

Franck
Franck

Reputation: 1764

Instead of using jquery $ service you should use angular $http which return a promise that you can attach to your scope. The promise by definition is defined right away and your scope will be populated when the promise is resolved. On top of that angular template fully understand promises and will display your model in the view as soon as it is ready.

Upvotes: 0

Related Questions