Question

I'am not pro in Angular and am still lerning. Hope I get some help here.

I want to build an App with different views. I need to detect the browser and also fetch some data from a server. For this I created a service, where I do this work.

My desire is to use the data of the service all views. How is proper way to store and cache the data so that I can use it in all my Views/Controllers?
Here is what I got so far.

My Service:

.factory('DataService', function($http, $q, $timeout) {
var data = { };
return {
    notes: function() {
        // This exposed private data
        return data;
    },
    addItem: function(itemname, itemvalue) {
        // This is a public function that modifies private data
        data[itemname] = itemvalue;
    }
    getPlatform: function() {
        var getPlatformData = function() {
          var deferred = $q.defer();
          BrowserDetect.init();
          deferred.resolve(BrowserDetect.OS);
            return deferred.promise;
        };
        return {
            getPlatformData: getPlatformData
        };
    },
    getServerData: function() {
        //if(!data.getServerData){
        var getData = function() {
            var deferred = $q.defer();
            $http({
                url: 'js/fakeGet.json',
                method: 'get',
                dataType: 'json',
            }).success(function(data) {
                data.scanResponse = data;
                deferred.resolve(data);
            })
            return deferred.promise;
        };

        return {
            getData: getData
        };
        //}
        // return data.scanResponse;
    }
};
});

My controller:

DataService.getPlatform().getPlatformData().then(function(platform) {
    console.log('Another browserDetect request');
    $scope.platform = platform;
    DataService.addItem("platform", $scope.userPlatform);
});
Was it helpful?

Solution

First of all, as nordyke mentioned in his answer, you'd better split the service to smaller ones.

Second, you're asking for how to caching the data, and since you're using promise, $q.when() is what you need. I will take the getPlatform as an example to get you started:

.factory('DataService', function($http, $q, $timeout) {
    var os; // this variable is used to store the result

    return {
        getPlatform: function() {
            var getPlatformData = function() {
                if (!os) { // no previous data available, look into other service to fetch the data
                    var deferred = $q.defer();
                    BrowserDetect.init();
                    os = BrowserDetect.OS; // store data
                    deferred.resolve(os);
                    return deferred.promise;
                }
                return $q.when(os); // there is previous data, return it as promise
            };
            return {
                getPlatformData: getPlatformData
            };
        }
    };
});

In this way, OS information is cached, and

DataService.getPlatform().getPlatformData().then(function(platform) {
    ...
});

will only fetch the platform information once during the life-time of the DataService. You can apply the same idea to getServerData as well to cache the data from the server.

OTHER TIPS

Caching your data in a service singleton is a good approach, and I like your straightforward implementation of it. My only recommendation would be to split up your 3 concerns into separate services.

  1. Browser Detection
  2. Server Requests (which will be split up even more once you have more requests.)
  3. Data Caching
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top