Chaitanya Munukutla
Chaitanya Munukutla

Reputation: 103

Socket.IO message doesn't update Angular variable

I have a socket.io client-server setup with AngularJS running on the client.

// Server.js
var io = require('socket.io')(server);


io.on('connection', function (socket) {
 socket.on('message', function (msg) {
    //console.log(msg);
    console.log(msg);
    io.emit('message', msg);
 });
});

As observed, it essentially emits a message events with the data stored in the variable msg.

And then I have the following client code.

var container = angular.module("AdminApp", []);

container.controller("StatsController", function($scope) {

    var socket = io.connect();

    socket.on('message', function (msg) {
        console.log(msg);
        $scope.frontEnd = msg;
    });
});

I now am facing a weird problem. When I write the following code snippet to print frontEnd, it doesn't show up. But the console.log(msg); works and it shows me the data emitted from the variable msg.

<body ng-app="AdminApp">

    <div ng-controller="StatsController">
        <p>{{frontEnd}}</p> //Doesn't show anything
    </div>

</body>

Can anyone help me out?

Upvotes: 6

Views: 1936

Answers (2)

Kalhan.Toress
Kalhan.Toress

Reputation: 21901

This is probably because socket.on('message', function (msg) {.. is out of angular knowledge. its something happening outside the angular.

Then if you o something outside of the angular then you have to tell the angular to update since there are something to update

use $scope.$apply() after the $scope.frontEnd = msg;

Or more preferably wrap it in the $timeout as,

$timeout(function() {
    $scope.frontEnd = msg;
});

here is a good explanation why $timeout is more preferable.

Upvotes: 0

Stefan
Stefan

Reputation: 14880

You need to wrap the change of the model (changing properties on the $scope), with $scope.$apply(function() {}) in order to to update the view.

var container = angular.module("AdminApp", []);

    container.controller("StatsController", function($scope) {

        var socket = io.connect();

        socket.on('message', function (msg) {
            console.log(msg);
            $scope.$apply(function() { $scope.frontEnd = msg; });
        });
    });

$apply() is used to execute an expression in angular from outside of the angular framework. (For example from browser DOM events, setTimeout, XHR or third party libraries). Because we are calling into the angular framework we need to perform proper scope life cycle of exception handling, executing watches.

From the official Angular Documentation

Upvotes: 9

Related Questions