I am really disappointed in Stack overflow. I had read the post which this is supposed to be a duplicate of several times and it did not help which is why I posted this one explaining why it was different, but STILL got marked as duplicate. Also, the way the callbacks are called in that alleged duplicate are different, and I could not apply them to the way I call my callbacks as I am not a rocket scientist or know the inner workings of javascript (although I have read 3 javascript books from cover to cover). I do have an answer now, and want to post the solution, but cant. So everyone in my situation, can't benefit from a documented solution which is different syntax from the duplicate.
I know there are lots of posts about this in javascript functions and objects, but there seems to be no similar help for javascript classes. classes are different because you cant use the "var self=this" trick to solve the problem. Solutions to not being able to get at class data include:
- bind. I have not been able to get this to work through the many levels of indirection required to make the program manageable. I cant find any examples of bind in callbacks without self (which doesnt work in classes) or the underscore library.
- arrow functions. these are fine if your entire logic is one line, but all mine are much larger and some need to be called from several places, so these are not an option I assume.
- var self = this. As mentioned this does not work in javacript classes.
Here is some code:
class Game{
constructor(minPlayers) {
this.minPlayers = minPlayers
this.players=[]
this.waitTimer=null
} // constructor
addPlayer(player) {
this.players.plush(player)
// if we are the first player, set a timeout waiting for others.
if (this.players.length ==1) {
this.waitTimer= setTimeout(this.waitForPlayers, 5000)
} else {
// stuff
}
} // addPlayer
// this function is too long to be an arrow function.
waitForPlayers() {
if (this.players.length < this.minPlayers) { // error this.xx undefined.
// do stuff
this.notifyAllPlayers("Game Aborted, not enough players")
} // else ....
}
notifyAllPlayers(message){
for (let i=0; i<this.players.length; i++) { // error this.players undefined
console.log(this.players[i].name) // error this.players undefined
}
}
} // Game
This is called by something like this:
let Game = require('./game')
let game= new Game(4)
game.addPlayer(bob)
The crux is how to get "this" from a function called by a callback called by a function? Where do all the binds go?
I have tried things like this:
this.waitTimer= setTimeout(this.waitForPlayers, 5000).bind(this)
and
waitForPlayers() {
// stuff
}.bind(this)
but these dont work.
== SOLUTION ==
sadly, I cant add this as an actual solution because the question has been incorrectly marked as a duplcate. Here is the solution:
this.waitTimer= setTimeout(this.waitForPlayers.bind(this), 5000)
This is how it was done in the "not a" duplicate:
transport.on('data', ( function () {
alert(this.data);
}).bind(this) );
Which I had read several times but didnt know how to apply to my case because it is not the same. I have no idea what transport.on is even. It might look the same to a rocket scientist, but stack overflow is also here to help non rocket scientists, or at least used to be.