0

I am using socket.io-client in a class, such that I do:

constructor() {
   socket.on("a", this.a.bind(this));
   socket.off("a", this.a.bind(this));
}

But when I construct (both on and then off fires), the socket still listens to "a".

The way I test this, is to console.log on a method, enter, and when "a" is received" console logs the event.

I also tried socket.removeListener, but it did not work.

Perhaps it is because it is a class method? How can I fix this to work?

Amit
  • 5,924
  • 7
  • 46
  • 94
  • It listens because "keep alive" header in request. You can't fix this. – Roman C Mar 24 '17 at 22:32
  • @RomanC If I do: `socket.removeAllListeners("a")` it stops this listener, so there is a way to stop it. I am looking for a more specific way – Amit Mar 24 '17 at 22:47
  • It doesn't work. – Roman C Mar 24 '17 at 22:48
  • @RomanC Why do you say that? It does work, to remove all listeners. – Amit Mar 24 '17 at 22:49
  • Which protocol socket do you have? – Roman C Mar 24 '17 at 22:54
  • @RomanC This is Socket.io (using socket.io-client). `on` listens to something, `off` should remove it, see here: http://stackoverflow.com/questions/23092624/socket-io-removing-specific-listener – Amit Mar 24 '17 at 22:56
  • But you can't remove the socket. – Roman C Mar 24 '17 at 22:57
  • @RomanC I am not trying to remove a socket, I am trying to remove a listener. To close the socket there is a method `socket.close()` – Amit Mar 24 '17 at 22:59
  • This you should call on destroy event. – Roman C Mar 24 '17 at 23:02
  • @RomanC I think you did not understand the question... I have a socket open all the time, for which I add and remove listeners at will. The removal part doesn't work when I bind the listener as a class method – Amit Mar 24 '17 at 23:06

1 Answers1

1

this.a.bind(this) returns a unique function each time so when you then try to use .off() with a second call to .bind(), you get a different function and thus it won't match the original so .off() doesn't find any matching function to remove.

You have to save the original bound function somewhere. You don't show enough of your code context to know where's a good place to save the original .bind() result.

Conceptually, you want to do something like this:

// save this somewhere that is per-instance and that both methods can access
// perhaps as an instance variable from the constructor
this.boundA = this.a.bind(this);

ngOnInit() {
   socket.on("a", this.boundA);
}
ngOnDestroy() {
   socket.off("a", this.boundA);
}

Demo of the issue:

class Foo {
  constructor() {
    console.log(this.a.bind(this) === this.a.bind(this))
  }
  a() {
   
  }
}

let f = new Foo();
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • I did not know bind creates a unique function, I will change the logic to reflect the above, and will update. (will be a day or so) Thanks. – Amit Mar 24 '17 at 23:11
  • @Amit - Try it yourself in the snippet I added to my answer. – jfriend00 Mar 24 '17 at 23:19
  • Thanks! Please see the edit, as it still fails to work even if I save in a different varaible – Amit Mar 25 '17 at 09:03
  • My mistake, I had a function that is calling the callback function, instead of passing it to the socket. Changed, and it worked – Amit Mar 25 '17 at 12:02