0

I'm new to javascript and ES6. How do I bind the websocket object into the callback I supply to subscribe? It feels wrong/wierd to me that I am accessing the websocket object from "global" scope like this.

const URL = 'echo.websocket.org';
const websocket = new WebSocket(`wss://${URL}`);
websocket.onmessage = (event)=>redux.dispatch(ChatActions.receiveMessage(event.data));
redux.subscribe(() => {
  const { lastAction } = redux.getState();

  switch (lastAction.type) {
    case ActionTypes.POST_MESSAGE:
      return websocket.send(lastAction.text);

    default:
      return;
  }
});
Baz
  • 12,713
  • 38
  • 145
  • 268
  • arrow functions get their `this` object from the surrounding environment. – Nina Scholz Oct 08 '16 at 17:56
  • for example, you can pass it as parameter to function, or you can use Singletone to retrieve a websoket – Telman Oct 08 '16 at 18:03
  • @Nina Scholz Can you elaborate please, for example what is meant by 'this' in this context? If the websocket object created on line two were to go out of scope, does it become undefined in my arrow function also. If so how do I avoid this, in other words how do I bind it into my arrow function. Is my code correct as it is? – Baz Oct 08 '16 at 18:04
  • for arrow functions have a look [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions). for you concrete problem i can not help. – Nina Scholz Oct 08 '16 at 18:07

2 Answers2

1

You will likely want to use a closure:

let webSocket = new WebSocket(url);

let takesWebSocket = socket => {
  return () => {
    // do stuff with the websocket
  };
};

let subscribeCallback = takesWebSocket(webSocket);

redux.subscribe(subscribeCallback);
Jared Smith
  • 19,721
  • 5
  • 45
  • 83
1

It feels wrong/wierd to me that I am accessing the websocket object from "global" scope like this.

No, this is exactly the correct solution. The arrow function forms a closure over the local websocket variable.

If your websocket variable is global, then that's a separate problem, whose solution will not affect the callback. You can wrap the whole thing in a function, IIFE, or block.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • So I should wrap my code above in (()=>{ })(); That way the websocket object will not be added to global scope and I will have avoided its namespace pollution and the possibility that someone else tries to use my websock object, which I don't want. Am I understanding correctly? – Baz Oct 09 '16 at 06:53
  • @Baz Yes, you can do that. But assuming you are using ES6 modules, your variables isn't global anyway, so you don't need the IIFE either. – Bergi Oct 09 '16 at 10:17