skip to Main Content

When I run the following code in my browser I get the following error. The error happens inside the #monitorConnection() method.

Cannot read private member #serverSocket from an object whose class
did not declare it

class ControlPanel {
    #serverSocket;
    constructor() {
        this.#connectToWebSocketServer();
        this.#monitorConnection();
        console.log("ControlPanel::new");
    }
    #connectToWebSocketServer() {
        this.#serverSocket = new WebSocket(window.location.toString().startsWith('https')
          ? window.location.toString().replace("https", "wss")
          : window.location.toString().replace("http", "wss")
        );
        this.#serverSocket.onclose = this.#onWebSocketClose;
        this.#serverSocket.onerror = this.#onWebSocketError;
        this.#serverSocket.onmessage = this.#onWebSocketMessage;
        this.#serverSocket.onopen = this.#onWebSocketOpen;
        console.log("ControlPanel::#connectToWebSocketServer");
    }
    #monitorConnection() {
        setInterval(function() { if(this.#serverSocket.readyState != 1) this.#connectToWebSocketServer() }, 1500);
    }
    #onWebSocketClose(event) {
        console.debug("ControlPanel::#onWebSocketClose ", event);
    }
    #onWebSocketError(event) {
        console.debug("ControlPanel::#onWebSocketError ", event);
    }
    #onWebSocketMessage(event) {
        console.log("ControlPanel::#onWebSocketMessage ", event);
    }
    #onWebSocketOpen(event) {
        console.debug("ControlPanel::#onWebSocketOpen ", event);
    }
}
const controlPanel = new slim.generator.ControlPanel(); 

When I update the following method it gets the same error when the websocket first connects.

    #onWebSocketOpen(event) {
        console.debug("ControlPanel::#onWebSocketOpen ", event);
        this.#serverSocket.send();
    }

2

Answers


  1. Chosen as BEST ANSWER

    Rojo,answered this for me.

    The problem is one of scope. The following added method works.

    #start() {
        var self = this;
        setInterval(() => { if(self.#serverSocket.readyState > 1) self.#connectToWebSocketServer() }, 1500);
    }
    

  2. The value of this in

    setInterval(function() {
       if(this.#serverSocket.readyState != 1) this.#connectToWebSocketServer() }
    , 1500);
    

    is undefined given code within class declarations runs in strict mode.

    Using an arrow function expression, which captures the lexical this value when evaluated, is the common solution:

    setInterval(() => { if(this.#serverSocket.readyState != 1) this.#connectToWebSocketServer() }
    , 1500);
    

    See Also: "No this substitution" under "Securing" JavaScript for discussion.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search