Search code examples
angularjslong-polling

AngularJS Long Polling - push result to list


Currently I can push long polling results to the $scope.newMsg variable, however I would like to add it to the messages list $scope.messages.push(msg).

This is my current app.js:

var messageApp = angular.module('messageApp', ['ngResource']);
messageApp.run(function(newMessagePoller) {});

messageApp.factory('messagesService', function($resource) {
    return $resource('/myapp/resources/message/all', {}, {
        query: {method: 'GET', isArray: true}
    });
});

messageApp.factory('newMessagePoller', function($http, $timeout) {
    var data = {response: {}};
    var poller = function() {
        $http.get('/myapp/newmsg').then(function(r) {
            data.response = r.data;
            $timeout(poller, 1);
        });
    };
    poller();
    return {data: data};
});

messageApp.factory('createMessageService', function($resource) {
    return $resource('/myapp/resources/message', {}, {
        create: {method: 'POST'}
    });
});

messageApp.factory('messageService', function($resource) {
    return $resource('/myapp/resources/message/:id', {}, {
        show: {method: 'GET'},
        update: {method: 'PUT', params: {id: '@id'}},
        delete: {method: 'DELETE', params: {id: '@id'}}
    });
});
messageApp.controller('messageCtrl', function($scope, newMessagePoller, createMessageService, messagesService, messageService) {
    $scope.messages = messagesService.query();
    $scope.newMsg = newMessagePoller.data;

    $scope.newMessage = function() {
        var newEntry = createMessageService.create($scope.message);
        $scope.messages.push(newEntry);
    };

    $scope.deleteMessage = function(msg) {
        messageService.delete({id: msg.id});
        $scope.messages.splice($.inArray(msg, $scope.messages), 1);
    };

    $scope.updateMessage = function(message) {
        messageService.update(message);
    };
});

I have tried passing the controller to the newMessagePoller:

messageApp.factory('newMessagePoller', function($http, $timeout, messageController) {
    var data = {response: {}};
    var poller = function() {
        $http.get('/basic-angularjs-ee/newmsg').then(function(r) {
            data.response = r.data;
            $timeout(poller, 1);
        });
    };
    poller();
    messagePoller.pushNewMessage(data.response);
});
...

$scope.pushNewMessage(msg) {
   $scope.messages.push(msg);
}

I guess my approach is wrong, any help would be much appreciated.

** Working code ** I have had to make the following changes to get the code working (thank you domakas):

messageApp.factory('newMessagePoller', function($http, $timeout) {
    var data = {data: ''};
    var poller = function() {
        $http.get('/myapp/newmsg').then(function(r) {
            data.data =  r.data;
            $timeout(poller, 1);
        });
    };
    poller();
    return data;
});

Assigned the response to the data attribute of the json structure.

$scope.$watch(
        function() { return newMessagePoller.data; }, 
        function(newMsg, oldMsg) {
            $scope.newMsg = newMsg;
            $scope.messages.push(newMsg);
        }
);

Added the $watch function to the controller.


Solution

  • It's hard to understand what is your ultimate goal here, but I think you should create watcher for your newMessagePoller in your controller and push message there:

    $scope.$watch(function() { return newMessagePoller.data; }, function(new, old) {
        if(new !== old) {
            $scope.messages.push(new);
        }
    });