0

I am new to JavaScript and have a good knowledge of C++. I want to store a callback function in a class and call it using the attribute in which it is stored:


class Connection
{
    #web_socket = 0;
    #log_text = null;

    constructor(url, log_callback)
    {
        this.#web_socket = new WebSocket(url);
        this.#web_socket.binaryType = "arraybuffer";
        this.#web_socket.onopen    = this.onOpen;

        this.#log_text = log_callback;
    }

    onOpen(event)
    {
        this.#log_text('Connection opened.');
    }
}

function displayConnectionState(state_message)
{
    document.getElementById('connection-state').innerHTML = state_message;
}

let connection = new Connection("ws://192.168.1.1:80", displayConnectionState);

But I get the following error: "Uncaught TypeError: Cannot read private member #log_text from an object whose class did not declare it at WebSocket.onOpen".

I searched on the web and suppose that the problem is that "this" does not refer to my Connection object. How do I solve that?

Dams
  • 11
  • 3
  • 2
    `this.#web_socket.onopen = this.onOpen;` -> `this.#web_socket.onopen = (e) => this.onOpen(e);` – VLAZ Nov 10 '22 at 15:58
  • In my code, the `onOpen(event)` function is well accessed. The problem is `this.#log_text('Connection opened.');`. `log_text` is not known. – Dams Nov 10 '22 at 16:26
  • Yes, because of the issue explained in the duplicate. If you pass a method by reference, then executing it will not pass the correct value of `this`, since the method reference is not associated with any instance. And the value of `this` is only determined at call time. See [How does the "this" keyword work, and when should it be used?](https://stackoverflow.com/q/3127429) One of the solutions (IMO, simplest) is to pass a function that calls the method. Thus the value of `this` at call time is correct. – VLAZ Nov 10 '22 at 16:32
  • @Dams did you try it? This is the solution. `this.#web_socket.onopen = e => this.onOpen(e)` or alternatively `this.#web_socket.onopen = this.onOpen.bind(this)`. – CherryDT Nov 10 '22 at 16:35
  • Thank you for your answers. I tried the solution proposed by VLAZ and it runs. I could reuse the method for other cases, but I still don't understand the way 'this' takes its value. The more I read about that, the less I understand. I don't find reasons why these mechanisms are so complicated. – Dams Nov 14 '22 at 12:49
  • Again, see [How does the "this" keyword work, and when should it be used?](https://stackoverflow.com/q/3127429) It's just that `this` is determined at call time. As a rule of thumb, a normal function call takes everything before the last dot as the value of `this`. `a.b.c()` will call `c` with `this = a.b`; while `a.b()` will call `b()` with `this = a`; and `a()` will call `a()` with `this = undefined`. When you do `x = a.b.c; x()` the call `x()` doesn't have anything before the last dot. Same thing happens with `function foo(cb) { cb() }` and `foo(a.b.c)` - at call time: `this = undefined` – VLAZ Nov 14 '22 at 13:00

0 Answers0