1

I am building a single page app using angular and .net backend. Aside from the individual restful resources that the controllers call, I also have a System Resource which provides the app with system wide information that is used/needed by most of my controllers. I call the system service and store the data in the rootScope when the user first logs on.

However if for some reason the user refreshes the page which will lose the rootScope then the system data is lost and no longer available to the controller.

I have managed to get the System Service to trigger if a page reload happens BUT the problem is that in many cases the services running from the controller happen BEFORE the system service call which means that the data is not always available when the controller runs.

Whats the correct way to handle this in angular? Is there a way to make my controllers dependent on a certain rootScope state which if necessary will cause my system service API to be called before the controller makes its own service calls?

Thanks

0

1 Answer 1

1

One approach could be creating a factory/service which is injected to and called by every controller needing this information. This way you don't have to mess with $rootScope.

The request to get information should be cached so that you don't have to fire off a get everytime you switch controller. If you want to persist the information even after a page refresh you could use localstorage to store your data.

Example factory:

angular.module('appName')
    .factory('Settings', ['$http', function ($http) {
        function getData() {
            var url = 'url/to/endpoint';
            return $http.get(url, {cache: true});
        }
        return {
            promise: getData()
        };
    }]);

By returning a promise from the factory we ensure that the getData() call is only run once. While in this particular instance it makes almost no difference (since it is returning an inner promise already), it is a pattern to follow for best practice.

This pattern also means that getData() is called on first use regardless of if the consuming controller accesses the promise. This allows for data to be exposed easily (data binding) without the need to use the promise in some use cases.

Used in controller:

angular.module('appName')
    .controller('VeryNiceCtrl', ['$scope','Settings', function ($scope, Settings) {
        Settings.promise.success(function(response){
            var appSettings = response;
            // do stuff
        })
}])
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks thats a good start. But how do I make my controller ALWAYS wait until the settings data has been retrieved. I dont know it firing off its own services until it has that data
Using the approach I posted you will always have access to your settings data as long as you do all of your controller magic inside the success function. E.g ; where i put the "// do stuff" comment
right, of course. Ok its not the prettiest solution but I was hoping for some special Angular magic to make it work. But given that thats not possible this is good! Thanks so much!
I prefer to return the promise not the function, as then you can still rely on it having completed without re-calling the expensive code each time.
You're very welcome to modify my answer with your approach, Is there a performance gain just returning the promise rather than the function? Mustn't the be function be called everytime anyway? @TimothyWalters

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.