Maxence Henneron
Maxence Henneron

Reputation: 495

Get right function inside of an object

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

Answers (6)

Renato Zannon
Renato Zannon

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

Patrick Evans
Patrick Evans

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

bto.rdz
bto.rdz

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

user1321425
user1321425

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

Andrei Nemes
Andrei Nemes

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

Alnitak
Alnitak

Reputation: 339836

Put:

var self = this;  // or other name to suit

and refer to self when you want the object.

Upvotes: 2

Related Questions