socket.io and angularjs ??

135 views
Skip to first unread message

biloki

unread,
Aug 18, 2013, 10:08:28 AM8/18/13
to ang...@googlegroups.com
I'm working on the project that uses angularjs and socket.io. I see on some projects that create socket that's a service like that

app.factory('socket', function ($rootScope) {
  var socket = io.connect(config.server);
  return {
    on: function (eventName, callback) {
      socket.on(eventName, function () {  
        var args = arguments;
        $rootScope.$apply(function () {
          callback.apply(socket, args);
        });
      });
    },
    emit: function (eventName, data, callback) {
      socket.emit(eventName, data, function () {
        var args = arguments;
        $rootScope.$apply(function () {
          if (callback) {
            callback.apply(socket, args);
          }
        });
      })
    }
  };
});

but like that, the socket will connect immediately when the app starts, but I want socket to connect when I click on a button like "Enter the room". I tried:

$scope.rooms= [];

$scope.connectFN= function(){
socket  = io.connect(config.server);
$("#btConnectFN").hide();

//connect
socket.on('connect', function(){

console.log("connected");
socket.emit('getRooms');

//listner on get rooms
socket.on('roomList', function(rooms) {
if (rooms.length>0){ //check number of rooms
for (var i=0;i<rooms.length;i++){
console.debug(i);
}
//$scope.rooms.push(5);
$scope.rooms = rooms;
}
});

});
}


But when I run this code, on the side client, $scope.rooms  = rooms  => that doesn't update the rooms of scope

So anyone can suggest for me how to do that ?

Thank you very much

Martin Alix

unread,
Aug 19, 2013, 4:32:24 PM8/19/13
to ang...@googlegroups.com
you need to surround that assignment with $apply too

Luke Kende

unread,
Aug 20, 2013, 2:56:18 AM8/20/13
to ang...@googlegroups.com
since socket is in a service, as soon as it is called as a dependency it will get instantiated... so looking at the service definition, you'd see why.  I haven't test this but just looking at it you might do...

app.factory('socket', function ($rootScope) {
 var socket = null;
  return {
   connect: function(){
       if (socket == null)
           socket = io.connect(config.server);
    },
    on: function (eventName, callback) {
      socket.on(eventName, function () {  
        var args = arguments;
        $rootScope.$apply(function () {
          callback.apply(socket, args);
        });
      });
    },
    emit: function (eventName, data, callback) {
      socket.emit(eventName, data, function () {
        var args = arguments;
        $rootScope.$apply(function () {
          if (callback) {
            callback.apply(socket, args);
          }
        });
      })
    }
  };
});


scope.rooms= [];

$scope.connectFN= function(){
  //jQuery in a controller is not good...
//$("#btConnectFN").hide();
                $scope.showButton = false; //use ng-show directive on the button - better way

                //start connection
                socket.connect();

//this starts the listener for a message of "connect" and will only fire when coming from the server
socket.on('connect', function(){
console.log("connected");
socket.emit('getRooms');
                 })
                 
                 //not sure why another listener was started within a listener so moved it out
  socket.on('roomList', function(rooms) {
if (rooms.length>0){ //check number of rooms
for (var i=0;i<rooms.length;i++){
console.debug(i);
}
$scope.rooms  = rooms;
}
});

});
}
Reply all
Reply to author
Forward
0 new messages