24

i'm currently working on a web based twitter client and therefore i used angular.js, node.js and socket.io. i push new tweets via socket.io to my client, where a service waits for new tweets. when a new tweet arrives, the service send an event via $broadcast.

in my controller is a event listener, where incoming tweets are being processed in an seperate function. this function simply pushes the new tweet in my tweet scope.

now, my problem ist, that my view is not updating but i can see my scope growing. maybe one of you have an idea, how i can solve this?

additionally my code:

service:

(function () {
    app.factory('Push', ['$rootScope', function ($rootScope) {
        socket.on('new-tweet', function (msg) {
            $rootScope.$broadcast('new-tweet', msg);
        });
    }]);
}());

controller:

(function () {
    app.controller("StreamCtrl", function StreamCtrl ($scope, $rootScope, $http, Push) {
        $scope.tweets = [];

        $http
            .get('/stream')
            .then(function (res) {
                $scope.tweets = res.data;
            });

        $scope.addTweet = function (data) {
            $scope.tweets.push(data);
            console.log($scope.tweets);
        };

        $rootScope.$on('new-tweet', function (event, data) {
            if (!data.friends) {
                $scope.addTweet(data);
            }
        });
    });
}());

the whole project is here: https://github.com/hochitom/node-twitter-client

1
  • 2
    try adding $scope.$apply() in addTweet and see results if view is updated or not Commented Apr 24, 2013 at 7:39

2 Answers 2

49

Adding below line of code in addTweet and the problem would be solved

$scope.addTweet = function (data) {
            $scope.tweets.push(data);
            $scope.$apply();
            console.log($scope.tweets);
        };
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you. $scope.$apply() helped me. Just curious - is this the correct way to update view? Meaning, shouldn't angular "decide" itself that the scope has changed?
That's a good question, jimhoskins.com/2012/12/17/angularjs-and-apply.html Jim Hoskins has a great summary as to why apply in this case, is needed.
Thanks a lot for the answer. $scope.$apply() worked for me. I used to set the controller dynamically using $injector.invoke(...). But could not get the $scope variables updated on the view. The $scope variables were updated only on key press or on blur, but when i used $scope.$apply(), the $scope variables were instantly updated on the view when the page loaded initially. Thanks a lot.
1

I prefer to use $timeout (don't forget to inject it to your controller) instead of $apply:

 app.controller("StreamCtrl", function StreamCtrl ($scope, $timeout $rootScope, $http, Push) {

    //...

    $scope.addTweet = function (data) {
        $timeout(function() {
            $scope.tweets.push(data);
            console.log($scope.tweets);
        });
    };

    //...

});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.