Error in defining class variable within the constructor not found

Just started delving into CoffeeScript and facing a challenge. In my code snippet below, I initialize WebSocketServer with a number as the first argument and a function as the second argument. However, when the websocket receives a message, @msgHandler suddenly becomes undefined. I attempted to resolve this by assigning @msgHandler to a variable named handler, but that also turned out to be undefined. Any suggestions or ideas on how to tackle this issue would be greatly appreciated. Thank you!

main.coffee

#Utilized for interaction with browser interface
webSocketServ = new sio.WebSocketServer Sauce.Server.WebSocketPort, (data, socketId) ->
    try
        json = JSON.parse(data)
        msgType  = json.msgType
    catch error
        return

    if (this.isAuthed(socketId))
        switch msgType
            when "auth"

            else
                io.websocket 'TODO: ' + cmd        
    else
        if msgType is 'auth'
            token = json.token

socket.coffee

class WebSocketServer
    constructor: (@port, @msgHandler) ->
        @webSockets = []
        @handlers = {}
        @test = []
        @authedSockes = []
        @listen(@port);
        console.log @msgHandler #msgHandler is defined here as [ Function ]

    listen: (port) ->
        @wsServ = engine.listen port
        @wsServ.on 'connection', @onConnect
        io.socket "WebServer socket started on port #{port}"

    onConnect: (client) ->
        io.websocket 'New connection with id of ' + client.id

        handler = @msgHandler #@msgHandler is undefined here?

        client.on 'message', (data) ->
            handler data, client.id
            io.websocket '[' + this.id + '] ' + JSON.stringify(data)

        client.on 'close', ->
            io.websocket '[' + this.id + '] Disconnect'

        client.on 'error', (err) ->
            io.websocket "IO error: " + err

compiled socket.coffee

  WebSocketServer = (function() {
    function WebSocketServer(port, msgHandler) {
      this.port = port;
      this.msgHandler = msgHandler;
      this.webSockets = [];
      this.handlers = {};
      this.test = [];
      this.authedSockes = [];
      this.listen(this.port);
      console.log(this.msgHandler);
    }

    WebSocketServer.prototype.listen = function(port) {
      this.wsServ = engine.listen(port);
      this.wsServ.on('connection', this.onConnect);
      return io.socket("WebServer socket started on port " + port);
    };

    WebSocketServer.prototype.onConnect = function(client) {
      var handler;
      io.websocket('New connection with id of ' + client.id);
      handler = this.msgHandler;
      client.on('message', function(data) {
        handler(data, client.id);
        return io.websocket('[' + this.id + '] ' + JSON.stringify(data));
      });
      client.on('close', function() {
        return io.websocket('[' + this.id + '] Disconnect');
      });
      return client.on('error', function(err) {
        return io.websocket("IO error: " + err);
      });
    };

    WebSocketServer.prototype.isAuthed = function(socketId) {
      return __indexOf.call(this.authedSockets, user) >= 0;
    };

    WebSocketServer.prototype.authSocket = function(socketId) {
      this.authedSockets.push(socketId);
      return io.websocket('Authenticated socket with ID of ' + socketId);
    };

    WebSocketServer.prototype.deauthSocket = function(socketId) {
      return this.authedSockets = this.authedSockets.filter(function(word) {
        return word !== socketId;
      });
    };

    return WebSocketServer;

  })();

Answer №1

There is an issue with accessing an instance property, not just an undefined class variable. This problem stems from the common this context issue in callbacks - where passing a method does not inherently give it knowledge of the instance.

To rectify this in CS, you can utilize the fat arrow syntax for method definitions and other callbacks:

    onConnect: (client) =>
#                       ^^
        io.websocket 'New connection with id of ' + client.id

        handler = @msgHandler # @ is now the expected instance

        client.on 'message', (data) =>
#                                   ^^
            handler data, client.id
            io.websocket '[' + @id + '] ' + JSON.stringify(data)
#                              ^ or did you mean to use `client.` here?

        client.on 'close', () =>
#                          ^^
            io.websocket '[' + @id + '] Disconnect'

        client.on 'error', (err) =>
            io.websocket "IO error: " + err

An alternative (and potentially better) solution could involve letting your WebSocketServer class inherit from the engine's class instead of creating a wrapper around it. Since callbacks are typically invoked on the server instance, direct access to properties would eliminate the need for callback binding.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring the Unpredictable Results of Recursive Functions in JavaScript

Take a look at this recursive code snippet. function calculateFactorial(n) { if (n === 0 || n === 1) { return 1; } else { console.log(calculateFactorial( (n - 1) )); return n * calculateFactorial(n - 1); } } const num = ...

Unable to establish a hyperlink to specific section of page using MUI 5 Drawer

When attempting to link to a specific part of my first page upon clicking the Shop button in the navigation Drawer, nothing happens: https://i.stack.imgur.com/FUQCp.png This snippet shows the code for the MUI 5 Drawer component: <Drawer anch ...

Tips for employing the slice approach in a data-table utilizing Vue

I have a unique situation in my Vue app where I'm utilizing v-data table. The current display of data in the table works fine, but I now want to enhance it by incorporating the slice method. Here is the current data displayed in the table: And here ...

Trouble with AJAX Post Request: Missing JSON Response

Below is the AJAX request I have created: var data = modalDom.find("form").serializeObject(); data["returnJson"] = true; $.ajax({ type: "POST", url: "/companies/edit/", data: data, dataType: "JSON", success: function (result) { ...

Adjusting the size of tables in raw JavaScript without altering their positioning

I am attempting to adjust the size of a th element without impacting the position of the next th in the row. Specifically, I want the width of the th to influence the width of the next th accordingly, rather than pushing it to the left. Below is the code ...

Merging a variable and its corresponding value in JavaScript

I am attempting to achieve a similar functionality in Angular javascript (with simplified code): var modelName = "date"; if (attrs.hasOwnProperty('today')) { scope.modelName = new Date(); } In the scenario above, my intention is for scope.m ...

prettyPhoto popup exceeds maximum width and height limitations

I am currently using the most up-to-date version from No Margin for Errors and I have set allow_resize to true. However, the size of the display is still too large. Is there a way to set a maximum width/height? I have already configured the viewport as fo ...

What's the best way to use JavaScript to obtain the width of a 'css-pixel' based on a media query?

While there have been discussions on how to determine device sizes using media queries like Twitter Bootstrap, I am looking for a reliable way to achieve the same output using JavaScript. Specifically, I want to get the CSS media query pixel number rather ...

Is it possible to retrieve 2 arguments within a function in a non-sequential manner?

Let's say there is a function with arguments A, B, C, D, and E. Function(A, B, C, D, E) However, not all arguments are needed all the time. For instance, only A and C are needed in some cases. Currently, I would have to call the function like this: Fu ...

Securing a REST API accessible through JavaScript by implementing authentication techniques due to the visibility of the public code

Inquiry: Need advice on securing an internal API intended for AJAX calls made within the website. I have developed a REST API in PHP 7.2 for use with client-side Javascript. Typically, I work on server-side applications where I can control access using a ...

The form I created retrieves select options via an ajax call, but after saving, the post values are not displaying as expected

I have created a form with the following HTML code snippet: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Populate City Dropdown Using jQuery Ajax</title> <script type="text/javascript" src="h ...

A guide to exporting a class in ReactJS

I am currently working on exporting some classes from my music player file - specifically playlist, setMusicIndex, and currentMusicIndex. const playlist = [ {name: 'September', src: september, duration: '3:47'}, {name: 'hello ...

Choose information based on the prior choice made

Using the Material UI Stepper, I have a task that involves setting conditions based on the selection of checkboxes. In step one, there are two checkboxes - Individual and Bulk. In step two, there are also two checkboxes - First Screening and Second Screeni ...

Display a JSX component based on a specific condition

As a newcomer to React, I am currently working on the navigation portion of my Navbar.js using the react-router-dom useLocation hook. I have successfully obtained the active path that leads to views and now I want to display custom text when a user reaches ...

Troubleshooting a Malfunctioning AJAX Request in a WordPress Plugin

After carefully reviewing this post about a jQuery Ajax call in a Wordpress plugin page, I found that it closely matched my current issue. My basic Wordpress plugin is designed to offer a specific membership form that passes payment details to PayPal for p ...

Unable to invoke a custom hook within another custom hook in a React application

I've developed a React application using create-react-app. Currently, I'm working on creating a custom hook that integrates with the Microsoft Authentication Library (MSAL). MSAL provides a custom React hook that I want to utilize within my own ...

Switch to a different form when clicked using JavaScript

Can you assist me with my code issue? The scenario is as follows: I have two forms - one for registration and one for login. I want to dynamically replace the login form with the register form when the user clicks on the "Sign up" link. Similarly, if the ...

Switch out text and calculate the frequency of letters in a given string

I have a string that looks like this: "061801850010300-09/A/B". My goal is to replace all "/" with "-" and also change "A" to "1" and "B" to "2". My objective is to assign each letter in the alphabet a numerical value - for example, A as 1, B as 2, C as 3 ...

Why isn't my callback working? Can anyone help me figure out what I did wrong?

I'm currently facing an issue while making an asynchronous call to Redis and attempting to utilize a callback to inform async.js about the completion of the query. I am consistently receiving an error message stating "callback is not a function". Can ...

Encountering a ReferenceError: require is undefined error when utilizing contextIsolation: true in conjunction with a preload script

My goal is to implement a select folder popup functionality, and I have written the following code for this purpose. Within the create-window.ts file, I have included these browserOptions.webPreferences: webPreferences: { nodeIntegration: true, conte ...