Angular JS – Polling Management + ViewModels

This time we want to find the best way to perform a polling to update some scope object (which we’ll refer as “dynamic object”) during out Angular application’s lifecycle. The basic idea is to have the polling logic nested within the dynamic object, instead of using something external. So what are we doing is to create a real auto-updating dynamic object. Let’s start from the controller: the myBlog property will be our dynamic object. We’ll use a dedicated service, called dataService, to provide it to us.

angular.module("myApp.controllers").controller("mainCtrl", ["$scope", "dataService", function ($scope, dataService) {
    $scope.myBlog = dataService.getMyblog();
}]);

Now let’s take a more deep look to our service: the getMyBlog() methods immediately returns an instance of myBlogObj, that as usual is added to our scope. This object exposes a public data property, which is the one we’ll refer from our scope. But this is a more smart object, so it includes as well the polling logic to get and to update this property. The getData() method does exactly this, checking for the sentinel feed as first step and, if something changed, updating the public data property from a fresh version of the feed. We can see from the example that the data property is not directly assigned to the feed’s content, but to an instance of myBlogViewModel, build on top of the feed’s content. This is our ViewModel, that we can use to transform the raw data coming from the feed to a more suitable format for our purposes.

angular.module("myApp.services").factory("dataService", ["$http", "$timeout", "config", function ($http, $timeout, config) {
    var service = function () {
        var self = this;
 
        self.getMyblog = function () {
 
            //MyBlog Object
            var myBlogObj = function () {
                var myBlogId = 3;
                var self = this;
 
                self.data = null;
                self.lastVersion = null;
 
                function getData() {
                    $http.get(config.SENTINEL_PATH.replace("{id}", myBlogId) + "?ts=" + new Date().getTime()).success(function (data) {
                        if (self.lastVersion == null || data.ts > self.lastVersion) {
                            self.lastVersion = data.ts;
 
                            $http.get(config.FEED_PATH.replace("{id}", myBlogId) + "?ts=" + self.lastVersion).success(function (data) {
                                if (self.data == null) {
 
                                    //Here we are assigning the data
                                    self.data = new window.myApp.myBlogViewModel(data, config);
                                }
                                else {
 
                                    //Here we are updating the data
                                    self.data.updateModel(data);
                                }
 
                                //Polling management
                                $timeout(getData, config.POLLING_INTERVAL);
                            });
                        }
                        else {
 
                            //Polling management
                            $timeout(getData, config.POLLING_INTERVAL);
                        }
                    });
                }
 
                function init() {
                    getData();
                }
                init();
            }
            return new myBlogObj();
        };
    };
    return new service();
}]);
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s