Reputation: 48198
I am sending an object from my server side to my client side, and the object that the client gets is totally different than the object I send. Here's what I mean:
Server side code:
//Basic setup for the example
var res={};
res.models=[];
res.models[0]={};
//The OLD (wrong) value
res.models[0]['id']="b4fd12f1-61ca-4445-b916-62617f1c0a78";
//The NEW (correct) value
res.models[0]['id']="fb8f83e2-e157-4e1e-8315-8e5f03b44691";
//Output what the id is, this is always the correct id!
console.log("res.models[0]['id']: ",res.models[0]['id']);
socket.emit("updateRealSeatSelect", res);
Client side code:
socket.on("updateRealSeatSelect", function(data){
//Output the id when we get the object. This is always wrong!
console.log("res.models[0]['id']: "+data.models[0]['id']);
});
The output is the problem. Here's what I get:
Server Side Output: (Correct)
res.models[0]['id']: fb8f83e2-e157-4e1e-8315-8e5f03b44691
Client Side Output: (Wrong! Why is it different??)
res.models[0]['id']: b4fd12f1-61ca-4445-b916-62617f1c0a78
I have double triple quadruple checked that the server is sending the correct object with the correct id. When the client gets the object, the object is different and has the wrong id! How can this happen?
Attempts:
I tried copying res
into a new object, then sending that, but that also didn't work. Like this:
var newres = res;
socket.emit("updateRealSeatSelect", newres);
I also tried using JSON.parse
and JSON.stringify
when I send the object but this didn't help either. Like this:
socket.emit("updateRealSeatSelect", JSON.stringify(res));
Versions:
Upvotes: 3
Views: 417
Reputation: 111258
Here is what I think really happens, even though it is not demonstrated in your code example.
Your object's ID looks like UUID which may suggest Cassandra. Even if it's not Cassandra it's probably some database and thus that object is retrieved asynchronously, but you return the response before the object is actually retrieved and you also keep the object in a global variable or in an outer scope that is shared between the invocations of socket.emit()
.
I also expect that the first socket.emit()
after you restart your server returns no object at all and all subsequent responses get the previous one.
So this is not like this:
//The OLD (wrong) value
res.models[0]['id']="b4fd12f1-61ca-4445-b916-62617f1c0a78";
//The NEW (correct) value
res.models[0]['id']="fb8f83e2-e157-4e1e-8315-8e5f03b44691";
socket.emit("updateRealSeatSelect", res);
But more like this:
database.getObject(function (data, res) {
if (err) {
// handle error
} else {
res = data;
}
});
socket.emit("updateRealSeatSelect", res);
roughly speaking. Of course it's just speculation because you didn't provide an example that would let us reproduce the problem and you didn't explain the most relevant parts of your code either.
If you get the data asynchronously using callbacks or promises then make sure that you don't try to emit it to the socket before you actually have it.
Also, always use:
'use strict';
at the beginning of your code to make sure that you don't implicitly declare global variables.
And read about concurrency in JavaScript - callbacks, continuation passing style, promises, async functions.
You may have more luck using async function than traditional callbacks and promise handling, so instead of something like this using callbacks:
getFromDatabase(function (err, data) {
if (err) {
// handle error
} else {
socket.emit('data', data);
}
});
or something like this using promises:
getFromDatabase().then(function (data) {
socket.emit('data', data);
}).catch(function (err) {
// handle error
});
you would write something like:
try {
socket.emit('data', await getFromDatabase());
} catch (err) {
// handle error
}
which may be more clear to follow the control flow.
Upvotes: 1