I have this class Game.
class Game {
constructor(player) {
this.player1 = player;
}
getHost() {
// player has property nickname
return `Host: ${this.player1.nickname}`;
}
}
I believe the issue I am having is that getHost() is becoming unbound from it's context, however I'm not sure how to fix it. I'm learning JS and I'm pretty confused about this language's usage of this
. I'm also using socket.io for the first time, so this adds a lot to the confusion for me.
My server script (the server works, just showing relevant parts):
io.on('connection', (socket) => {
// passed defined player
socket.on('host game', (player) => {
const game = new Game(player);
console.log(game.getHost()); // still works here
io.sockets.emit("game created", game);
});
});
Client:
socket.on("game created", (game) => {
const gameElement = document.createElement("li");
gameElement.innerHTML = game.getHost(); // ERROR
games.appendChild(gameElement);
});
On the above marked line, I get the Uncaught TypeError: game.getHost is not a function
.
Sorry if the socket.io functions make it more confusing, basically just when the game is passed from server to client, it doesn't work anymore.
Thanks for the help
The issue is that socketio is serializing the object for you. Since a websocket is still just HTTP, you can't send an actual JS object over it. socketio handles serializing your object to JSON using JSON.stringify(game)
behind the scenes. It will also convert that JSON string back into an object for you on the client side too.
Unfortunately when you do this you lose methods. For example:
let game = new Game({nickname: 'Bob Vance'});
game = JSON.stringify(game);
console.log(game) // will output {"player1":{"nickname":"Bob Vance"}}
You should see {"player1":{"nickname":"Bob Vance"}}
in the console because serializing to JSON drops the methods but preserves properties. This is just normal JavaScript behaviour.
So what you have to do to get the methods back is create a new instance of a game on the client-side, and then use Object.assign()
to build the object back up.
Example
let serializedGame= JSON.parse(game);
let newGameInstance = new Game({nickname: game.nickname});
Object.assign(newGameInstance, serializedGame);
Now you should be ok to call newGameInstance.getHost()