I've setup my Node server to push out some data at random intervals, and the data is getting to the client/browser; however, I can't figure out how to access it in my app's controller.
#node.js file: /server.js (truncated for brevity)
var http = require('http').createServer(handler),//refers to handler()
fs = require('fs'),
io = require('socket.io').listen(http);
http.listen(8000);
…
io.sockets.on('connection', function (socket) {
/* DUMMY CODE: this generates fake alerts at random intervals */
(function loop() {
var rand = Math…;
…
setTimeout(function(){
…
var alert = { … };
socket.emit('alert', {
"alert": alert
});//socket.emit()
loop();
}, rand);
}());
});//io.sockets.on()
When I log alert
to Terminal, it looks like this:
alert: {
id: 258,
lat: -95.20933,
long: 37.027676,
neighbourhood: "Downtown",
time: //stringified js timestamp
}
And arguments
from below contains the data I want (basically same as alert
).
# /app/js/services.js
angular.module( 'BAR.services' , [])
.factory('socketio', function($rootScope){
var socket = io.connect();
return {
on: function(event, callback) {
socket.on(event, function(){
//console.log(arguments);
$rootScope.$apply(function(){
callback.apply(socket, arguments);
});//$rootScope.$apply()
});//socket.on()
},//on
emit: function(event, data, callback) {
socket.emit(event, data, function(){
//console.log(arguments);
$rootScope.$apply(function(){
if (callback) callback.apply(socket, arguments);
});//$rootScope.$apply()
});//socket.emit()
},//emit
disconnect: function() {
socket.disconnect();
}
}//return
});// AlertServices
However, I can't figure out how to access the data from arguments
in my controller:
# /app/js/controllers.js
function Alerts( $scope , socketio ) {
socketio.on('alert', function(data) {
console.log(data); /* I expect this to be the data I want */
$scope.alert = data.alert;
});
$scope.disconnect = function(){
socketio.disconnect();
}
}
Alerts.$inject = ['$scope','socketio'];
When I log data
to the browser's console here in the controller, I get an enormous object that seems to be the parent of $scope
; and data.alert
is undefined. I also tried to specify a second parameter like this socketio.on('alert', function( data , args )
thinking it might be arguments
(since callback.apply( … )
in services has 2), but when I did and logged it to console, args
returned undefined.
Btw, I based this on a tutorial by an AngularJS intern. Different pieces had the same names, so I had a bit trouble figuring out what each the different peices did (also it was not helpful that it was in Jade).
What I really want to do is update a binding in my view with the data from alert
.
In your on
and emit
functions, you're using:
socket.on(event, function() {
$rootScope.$apply(function() {
callback.apply(socket, arguments);
});
});
but in the original version of this from the tutorial, it says:
socket.on(eventName, function() {
var args = arguments;
$rootScope.$apply(function () {
callback.apply(socket, args);
});
});
The var args = arguments
is important, as it sets args
to the arguments passed to the callback to socket.on
(which is the data you're looking for). Without this step, when you actually use arguments
, it resolves to the arguments passed into the callback to $rootScope.$apply
(which is an Angular scope according to the documentation, explaining why you get the console output you do).
The solution would be to capture the arguments outside of the call to $apply
and pass those into your callback:
socket.on(event, function() {
var args = arguments;
$rootScope.$apply(function() {
callback.apply(socket, args);
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With