3

Now I'm trying to implement Unity Webgl with jslib. I'm so confused about how to call method in another method's function. I want to call method Recv when message was coming (ws.onmessage). But, it show "TypeError: this.Recv is undefined". Could you please help me figure out this source?
Thank you !!!!!

Here's my source code

var ws = null;
var init_url = "";
var received_msg = "";
var error_msg = "";

var WebsocketLib = {
Hello: function(){
    window.alert("Hello,world!");
},
InitSocket: function(url){
    init_url = Pointer_stringify(url);
    console.log("InitWebSocket: "+init_url);
    ws = new WebSocket(init_url);
    ws.onopen = function(evt){ 
            console.log("Connect");
            isConnected = false;
            ws.send("hello");
        }; 
    ws.onclose = function(evt) { 
            console.log("Close");
            isConnected = false;
        }; 
    ws.onmessage = function(evt) {
            received_msg = evt.data;
            console.log("[recv] "+received_msg);
            this.Recv.call(this);
        }; 
    ws.onerror = function(evt) {
            error_msg = evt.data;
            console.log("[error] "+error_msg);
            this.Error.call(this);
        };
},
Recv: function(){
    console.log("[recv] "+received_msg);
    var buffer = _malloc(received_msg.length + 1);
    writeStringToMemory(returnStr, buffer);
    return buffer;
},
Error: function(){
    console.log("[error] "+error_msg);
    var buffer = _malloc(error_msg.length + 1);
    writeStringToMemory(error_msg, buffer);
    return buffer;
}
}

2 Answers 2

2

Inside of ws.onmessage this will refer to ws (as we're inside a method of ws) and not WebsocketLib.

However, inside Initsocket, where you define the handlers, this would correctly (in the sense that this is what you want) refer to the WebsocketLib object, so you can create a bound function to bind the outer this value to be used as this inside the event handler, like this:

ws.onmessage = function(evt) {
        received_msg = evt.data;
        console.log("[recv] "+received_msg);
        this.Recv.call(this);
}.bind(this); 
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your answer. It's really clear and easy to understand.
2

in JavaScript the value of this behaves differently than in other languages. Its value depends on how the function is called. You can read more about it in the Mozilla MDN page.

To solve your specific problem you can:

InitSocket: function(url){
    var that = this;                                  // [1]
    init_url = Pointer_stringify(url);
    console.log("InitWebSocket: "+init_url);
    ws = new WebSocket(init_url);
    ws.onopen = function(evt){ 
            console.log("Connect");
            isConnected = false;
            ws.send("hello");
        }; 
    ws.onclose = function(evt) { 
            console.log("Close");
            isConnected = false;
        }; 
    ws.onmessage = function(evt) {
            received_msg = evt.data;
            console.log("[recv] "+received_msg);
            that.Recv.call(that);                     // [2]
        }; 
    ws.onerror = function(evt) {
            error_msg = evt.data;
            console.log("[error] "+error_msg);
            that.Error.call(that);                    // [2]
        };
},

In line 1 I bind the this variable to a custom variable that I decided to call that (but you can call it as you want). Then in line 2 I used that instead of this.

Inside the ws.onmessage function the value of this is not referring to the instance of WebsocketLib, so you need to use this "trick" and access the right this value using the one saved in the closure, inside the value of that.

4 Comments

Thank you for your answer :)
I am a learner. So I suppose that this.Error.call(this) won't work neither, right?
Yes, for the same reason this.Error.call(this) does not work, you have to change this to that. For a better understanding of this you can read the MDN article I suggested and this StackOverflow.
Just edited my answer to correct "this.Error.call(this)" to "that.Error.call(that)" and "that.Recv.call(this);" to "that.Recv.call(that);". You need to change the this inside the "call(this)" for the same reason I explained. Otherwise, the "Recv" and "Error" function calls will not be bind to the correct object instance.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.