Reputation: 495
in this code, on line 15 the "this" pointer refers to socket and not my Object Network. What should I do to actually get the Network object? Sorry for this "noob" question but I searched for a while on google and I didn't even know what to type to find an answer..
var Network = function(ip, port){
this.host = "ws://"+ip+":"+port;
this.socket = new WebSocket(this.host);
this.socket.binaryType = "arraybuffer";
var ByteBuffer = dcodeIO.ByteBuffer;
this.socket.onopen = function(){
console.log('Connected to the WebSocket server');
};
this.socket.onmessage = function(e){
var bytearray = new Uint8Array(e.data);
switch(bytearray[0])
{
case 2: this.handleLoginAnswer(bytearray); break; //line 15
default:
alert("received a wrong packet")
}
};
this.handleLoginAnswer = function(packet){
var bytearray = new Uint8Array(e.data);
var reader = ByteBuffer.wrap(bytearray);
var opcode = reader.readUint8();
if(opcode != 2)
return;
var result = reader.readUint8();
switch(result){
case 1: displayValidate("Sucessfully registered"); break;
case 2: displayError("Username is already taken"); break;
case 3: displayError("Email is already taken"); break;
}
function displayValidate(message){
$("#register-messagebox").html("<div class=\"alert-message\" style=\"background-color:#27ae60;\">" + message + "</div>");
}
function displayError(error){
$("#register-messagebox").html("<div class=\"alert-message\" style=\"background-color:#e74c3c;\">" + error + "</div>");
}
}
}
Upvotes: 0
Views: 82
Reputation: 29971
That's a common issue. An option is to maintain reference to it, using the closure:
// Get a reference to the network
var network = this;
this.socket.onmessage = function(e){
var bytearray = new Uint8Array(e.data);
switch(bytearray[0]) {
// Access the outside-defined 'network' here
case 2: network.handleLoginAnswer(bytearray); break;
default:
alert("received a wrong packet");
}
};
Another one is to use Function.bind
, to force the handler to be executed with network
being the this
, instead of the socket
:
this.socket.onmessage = function(e){
var bytearray = new Uint8Array(e.data);
switch(bytearray[0]) {
// It's safe to use 'this' here
case 2: this.handleLoginAnswer(bytearray); break;
default:
alert("received a wrong packet");
}
// Bind the function, so that it is always executed in this context
}.bind(this);
In your case, yet another one is to not use this
to refer to the handleLoginAnswer
function, since it is defined on the same place anyway. If you change it's definition from this:
this.handleLoginAnswer = function() { /* ... */ };
to this:
var handleLoginAnswer = function() { /* ... */ };
And the call from:
this.handleLoginAnswer(bytearray);
To:
handleLoginAnswer(bytearray);
Upvotes: 1
Reputation: 42736
Save a reference of this, and then use the reference instead of this
var Network = function(ip, port){
var _this = this;
...
case 2: _this.handleLoginAnswer(bytearray); break; //line 15
Upvotes: 1
Reputation: 6720
a common answer to this problem is this:
var myclass = function () {
var self = this;
self.host = 'my host';
self.goHere = function () {
//here use self to refer to myclass or this to refer to goHere function
}
};
Upvotes: 1
Reputation:
Immediate invocation is your friend:
this.socket.onmessage = function(that) {
return function(e) {
// Your callback code here, where `that` is referencing your `Object Network`
}
}(this);
Upvotes: 1
Reputation: 3122
Inside your Network
object, cache the reference to this
:
var self = this;
And then you may access it using self
instead of this
case 2: self.handleLoginAnswer(bytearray); break; //line 15
Because the way JavaScript closures work, you will have access to self
from within
Upvotes: 2
Reputation: 339836
Put:
var self = this; // or other name to suit
and refer to self
when you want the object.
Upvotes: 2