3

I am quiet new to AngularJS and have a quick question about refreshing a page only when new data is retrieved from the server.

I have searched around but couldnt find anything similar to my problem.

I have a Service and Controller with an intervalPromise as follows:

MyService

angular.module('MyService', ['ngResource']).
    factory('Data', function($resource){
      return $resource('rest/getMyData', {});
});

MyController

function MyController($scope,$interval,$http, Data) {

    $scope.refresh = function() {
        $scope.jobs = Data.query();
    };

    $scope.intervalPromise = $interval(function(){
          $scope.refresh();
    }, 10000);  

    // initial load of data
    $scope.refresh();
}

Data is retrieved from the server successfully every 10 seconds, but I would like the page to refresh only when new data is found.

A point in the right direction would be much appreciated.

user1694873
  • 473
  • 1
  • 11
  • 21
  • 1
    Could you give us a little more context? What is your goal? What is wrong with your current method? – Ryan Warner Jan 28 '15 at 00:34
  • Currently the page visibly refreshes every ten seconds and reloads the data retrieved from the server even if it is the same data before the refresh. So my goal is that when I call $scope.refresh the page does not visibly refresh if the data is the same. Hope I'm making sense – user1694873 Jan 28 '15 at 00:39
  • 1
    It could be cause by delay between the request and response, does this post help at all? http://stackoverflow.com/questions/16352690/non-flickering-polling-in-angular-with-rest-backend – Ryan Warner Jan 28 '15 at 00:50
  • I'm away from my pc right now, will try first thing tomorrow, thanks for your help so far. Sounds like it could be what I'm after alright, cheers – user1694873 Jan 28 '15 at 01:05
  • http://stackoverflow.com/questions/16352690/non-flickering-polling-in-angular-with-rest-backend This answer fixed the problem for me, thanks @Ryan Warner – user1694873 Jan 28 '15 at 19:23

2 Answers2

3

You could compare the data received from the server to your current data set ($scope.jobs) and only update $scope.jobs if they are different.

function MyController($scope,$interval,$http, Data) {

    $scope.refresh = function() {
        var serverData = Data.query();
        if( serverData !== $scope.jobs ) {
            $scope.jobs = serverData;
        }
    };

    $scope.intervalPromise = $interval(function(){
          $scope.refresh();
    }, 10000);  

    // initial load of data
    $scope.refresh();
}
Ryan Warner
  • 1,354
  • 1
  • 10
  • 7
  • Hi, That did not work but I see where you are coming from. There is no way this is handled automatically by Angular? Backbone.js had a sync function which handled this for me when I worked with that previously as far as I remember – user1694873 Jan 28 '15 at 00:20
1

I think I've found a solution that works.

Ryan's answer doesn't work for me either. After a bit of digging it seems that it doesn't quite work correctly as the Data.query() operation takes a short time to return - and it hasn't done by the time it gets to the comparison in the if(...) - so the refresh always gets invoked (and the screen just "flashes" every ten seconds as it refreshes to the same data).

To fix it, you need to add a delay with setTimeout().

function MyController($scope,$interval,$http, Data) {
  $scope.refresh = function() {
      var serverData = Data.query();
      setTimeout(function(){
            if (serverData !== $scope.jobs){
               $scope.jobs = serverData;
            }
      }, 100);
  };

  $scope.intervalPromise = $interval(function(){
      $scope.refresh();
  }, 10000);  

  // initial load of data
  $scope.refresh();
}

Anyway that works for me - so it might be useful if anyone's still having difficulty.

AJ Poulter
  • 1,717
  • 2
  • 10
  • 9