Search code examples
javascriptangularjsoptimizationajax-polling

Make AngularJS skip running a digest loop if $http.get() resulted in no new data


I'm currently polling the server to check for new data, and then update the model in an AngularJS app accordingly. He're roughly what I'm doing:

setInterval(function () {
    $http.get('data.json').then(function (result) {
        if (result.data.length > 0) {
          // if data, update model here
        } else {
          // nothing has changed, but AngularJS will still start the digest cycle
        }
    });
}, 5000);

This works fine, but most of the requests will not result in any new data or data changes, but the $http service doesn't really know/care and will still trigger a digest cycle. I feel this is unnecessary (since the digest cycle is one of the heaviest operations in the app). Is there any way to still be able to use $http but somehow skip the digest if nothing has changed?

One solution would be to not use $http but jQuery instead, and then call $apply to let Angular know that the model has changed:

setInterval(function () {
    $.get('data.json', function (dataList) {
        if (dataList.length > 0) {
            // if data, update model
            $scope.value = dataList[0].value + ' ' + new Date();

            // notify angular manually that the model has changed.
            $rootScope.$apply();
        }
    });
}, 5000);

While this seems to work, I'm not sure it's a good idea. I would still like to use pure Angular if possible.

Anyone got any suggestions for improvements to the approach above or a more elegant solution entirely?

P.S. The reason I'm using setInterval instead of $timeout is because $timeout would also trigger a digest cycle which would be unnecessary in this case and only add to the "problem".


Solution

  • Web sockets would seem to be the most elegant solution here. That way you don't need to poll the server. The server can tell your app when data or anything has changed.