Organizational Research By

Surprising Reserch Topic

server polling with angularjs


server polling with angularjs  using -'javascript,angularjs'

I'm trying to learn AngularJS.  My first attempt to get new data every second worked:

'use strict';

function dataCtrl($scope, $http, $timeout) {
    $scope.data = [];

    (function tick() {
        $http.get('api/changingData').success(function (data) {
            $scope.data = data;
            $timeout(tick, 1000);
        });
    })();
};


When I simulate a slow server by sleeping the thread for 5 seconds it waits for the response before updating the UI and setting another timeout.  The problem is when I rewrote the above to use Angular modules and DI for module creation:

'use strict';

angular.module('datacat', ['dataServices']);

angular.module('dataServices', ['ngResource']).
    factory('Data', function ($resource) {
        return $resource('api/changingData', {}, {
            query: { method: 'GET', params: {}, isArray: true }
        });
    });

function dataCtrl($scope, $timeout, Data) {
    $scope.data = [];

    (function tick() {
        $scope.data = Data.query();
        $timeout(tick, 1000);
    })();
};


This only works if the server response is fast. If there's any delay it spams out 1 request a second without waiting for a response and seems to clear the UI. I think I need to use a callback function. I tried:

var x = Data.get({}, function () { });


but got an error: "Error: destination.push is not a function"  This was based on the docs for $resource but I didn't really understand the examples there.

How do I make the second approach work?
    

asked Oct 7, 2015 by mca.agarwal
0 votes
572 views



Related Hot Questions

2 Answers

0 votes

More recent versions of angular have introduced $interval which works even better than $timeout for server polling.

var refreshData = function() {
    // Assign to scope within callback to avoid data flickering on screen
    Data.query({ someField: $scope.fieldValue }, function(dataElements){
        $scope.data = dataElements;
    });
};

var promise = $interval(refreshData, 1000);

// Cancel interval on page changes
$scope.$on('$destroy', function(){
    if (angular.isDefined(promise)) {
        $interval.cancel(promise);
        promise = undefined;
    }
});
answered Oct 7, 2015 by ukohale
0 votes

You should be calling the tick function in the callback for query.

function dataCtrl($scope, $timeout, Data) {
    $scope.data = [];

    (function tick() {
        $scope.data = Data.query(function(){
            $timeout(tick, 1000);
        });
    })();
};
answered Oct 7, 2015 by deepak07.s

...