I am fairly new to JavaScript, and I have been having issue with the scope of what I think is a global variable.
Here is where I receive the data from the user via Socket.IO: (server.js)
var locationData = {lat: '-20', long: '20'};
var latNumber;
var longNumber;
//SocketIO data
var chat = require('express')();
var http = require('http').Server(chat);
var io = require('socket.io')(http);
io.sockets.on('connection', function (socket) {
socket.on('new message', function (msg) {
locationData = msg;
latNumber = parseFloat(locationData.lat);
longNumber = parseFloat(locationData.long);
io.emit('message', msg.message);
});
});
http.listen(5670, function(){
console.log('listening on *:5670');
});
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
function getLat(){
return latNumber;
}
function getLong(){
return latNumber;
}
Here is the HTML script where I want to receive that data: (HelloWorld.html)
<script type="text/javascript" src="/server.js"></script>
<script>
var viewer = new Cesium.Viewer('cesiumContainer');
var citizensBankPark = viewer.entities.add({
name : 'Test',
position : Cesium.Cartesian3.fromDegrees(getLat(),getLong()),
point : {
pixelSize : 5,
color : Cesium.Color.RED,
outlineColor : Cesium.Color.WHITE,
outlineWidth : 2
},
label : {
text : 'Test',
font : '14pt monospace',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth : 2,
verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
pixelOffset : new Cesium.Cartesian2(0, -9)
}
});
viewer.zoomTo(viewer.entities);
</script>
I am trying to read the data from latNumber and longNumber defined and set in server.js into the position assignment in HelloWorld.html. The problem I am having is that once the data gets to HelloWorld.html it is undefined, and gives an error in the browser.
Now what I am not sure about is why is it undefined. Logging the latNumber and longNumber variables in server.js work fine and have data in them. Also changing the return statements in the getLat() getLong() to a hardcoded variable such as 15 works fine, and passes it onto HelloWorld.html, where it then does what it is supposed to do. It only errors out when I combine the two together!
Any help or pointers would be much appreciated! Thanks!
You've got quite a mix of issues here. Your server.js
file doesn't look like client-side code at all, it looks like it's supposed to be running the server via Node.js. Are you using Node.js to run server.js
to listen on port 5670, as this code suggests?
If so, good, but get rid of the <script src="/server.js">
reference on the client code. You don't want the client reading the server's source code (and ideally it shouldn't even be served, but that's a different topic).
So now you have a new problem: Your server has getLat
and getLon
functions that no longer exist at all on the client. You need to transmit the information from server to client.
In server.js, you can add some code to make these numbers available via REST:
chat.get('/location', function(req, res, next) {
var response = {
lat: latNumber,
lon: lonNumber
};
res.type('application/json');
res.send(JSON.stringify(response));
});
This server code will listen for requests for the URL /location
and respond with a JSON string containing the numbers.
Next, your client code should request these values from the server, asynchronously (meaning we don't lock up the browser's UI while waiting for the server to respond). This is done like so:
var viewer = new Cesium.Viewer('cesiumContainer');
Cesium.loadJson('/location').then(function(data) {
viewer.entities.add({
name : 'Test',
position : Cesium.Cartesian3.fromDegrees(data.lon, data.lat),
point : {
pixelSize : 5,
color : Cesium.Color.RED,
outlineColor : Cesium.Color.WHITE,
outlineWidth : 2
},
label : {
text : 'Test',
font : '14pt monospace',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth : 2,
verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
pixelOffset : new Cesium.Cartesian2(0, -9)
}
});
viewer.zoomTo(viewer.entities);
});
In the above code, loadJson
returns a promise to get the data, and we add a callback function to execute when the promise resolves. The callback receives the server's data as a parameter, and builds a new entity. You can see the entity's position is based on data received from the server.
If the server's idea of the location changes, you may need to have the client periodically poll for the new location, or you can use a number of different technologies (long-polling, server-side push, EventSource, WebSockets, etc.) to get the client to update. But for starters, just reload the client page to see the new location.