Gotts
Gotts

Reputation: 2454

Call an API in every angular controller if data not yet loaded

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

Upvotes: 1

Views: 783

Answers (1)

Erik Svedin
Erik Svedin

Reputation: 1286

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
        })
}])

Upvotes: 1

Related Questions