Question

I am simulating polling a server by manually changing db values, and allowing my controller to query the api every 10 seconds. Things work, however if the DB changes, then the value in the view switches to 0 before changing to the number it should be.

Controller

messageControllers.controller('NavigationCtrl', ['$scope', '$routeParams', 'Message', '$timeout',
    function ($scope, $routeParams, Message, $timeout) {

        var messages = Message.query({ type:'inbox' });
        $scope.inbox = messages;

        var poll = function() {
            $timeout(function() {
                var messages = Message.query({ type:'inbox' });
                $scope.inbox = messages;
                poll();
            }, 10000);
        };     
       poll();
}]);

Snippet from View

<li><a data-ng-href="#/">Inbox <span class="badge"><% (inbox|filter:{read:false}).length %></span></a></li>

e.g. if the number of read==false results is 5, then the db changes and now the number of read==false results is 6. What happens is instead of <% (inbox|filter:{read:false}).length %> changing straight to 6, it changes to 0 first.

Just getting to grips with Angular, and don't really understand what I am doing so sorry if this is a dumb question!!!

I have a feeling that it has something to do with the bound value in (inbox|filter:{read:false}).length being empty whilst AngularJS is waiting for the data, however I have no idea how to change this so that $scope.inbox only changes once Message.query is complete.

Was it helpful?

Solution

Message.query({ type:'inbox' }); is an async request.

It will return a reference object, which is populated after the query is finished. From the docs:

It is important to realize that invoking a $resource object method immediately returns an empty reference (object or array depending on isArray). Once the data is returned from the server the existing reference is populated with the actual data.

Handily, you can access the promise which is resolved when the query finishes using the $promise property.

So try changing your code inside the timeout function to the following:

var messages = Message.query({ type:'inbox' });

// Populate the scope only after the query has resolved.

messages.$promise.then(function(){
  $scope.inbox = messages;
});

poll(); 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top