81

I'm using Socket.io v0.9.16 and Chrome 34

I'm trying to remove a specific listener, or unsubscribe from a specific subscription

Something like this:

socket.on('testComplete',function(data){
    console.log('test complete',data);
}); 

function emitTest(){
    console.log('emitting test');
    socket.emit('test','first emit');
}

function removeListener(){
    socket.removeListener('testComplete');
}

If I call the emitTest function, and then the removeListener function, I still see the 'test complete' message when I call emitTest again. The listener should have been removed, if the socket function even works.

I'm looking for a way to remove a specific listener that actually works.

This answer says that removeListener doesn't work.

Is there any downside to just doing this:

socket.removeListener=function(name){
        if(socket.$events.hasOwnProperty(name)){
            delete socket.$events[name];
        }
    };

I marked an answer as correct, but I'm using the above in my code since it works better with my design.

Community
  • 1
  • 1

3 Answers3

138
//To unsubscribe all listeners of an event
socket.off('event-name');

//to unsubscribe a certain listener
socket.off('event-name', listener);

Note that socket.off, socket.removeListener, socket.removeAllListeners, socket.removeEventListener are synonyms.

This is tested on socket.io v1.4.3

Israfel
  • 1,652
  • 1
  • 12
  • 6
  • 2
    I'm using socket.io 2.0.x and can confirm this works both for specific listeners and without specifying a specific listener to just unbind all functions (including anonymous functions). – Iain Collins Aug 14 '18 at 16:20
  • With socket.io 2.3.0, the socket.off() event throws an error, if I invoke it without a second parameter, which has to be a function. I presume, the specific function that I want to remove. – Adam Baranyai Feb 08 '20 at 01:21
  • I've managed to remove all the event listeners using `socket.removeAllListeners("news");` found in this answer: https://stackoverflow.com/a/9696077/2691879 – Adam Baranyai Feb 08 '20 at 01:26
  • I'm using socket.io version 2.3.0 and `off` is not defined on the server side when obtaining the socket object through `io.on(eventName, (socket) => {...})`. However, `removeListener` works just fine in this case. – nullromo Apr 07 '20 at 04:41
54

You need to pass in the listener function to removeListener.

function testFun(data){
    console.log('test complete',data);
}

socket.on('testComplete', testFun); 

function emitTest(){
    console.log('emitting test');
    socket.emit('test','first emit');
}

function removeListener(){
    socket.removeListener('testComplete', testFun);
}
Lyn Headley
  • 11,368
  • 3
  • 33
  • 35
  • Why twice as many? You just have to have a reference to the function you passed in. This is the way all EventEmitters on Node work, as well as the convention in browser libraries. If you have an unknown number of handlers registered for a given event and need to remove them all, I think your solution is sensible though. – Semicolon Jul 29 '14 at 21:53
0

Update 2023: All of the major browsers have decided against supporting getEventListeners. Only Chrome supports it from the command line!

If you're not using a function call, or even if you are the following worked for me:

getEventListeners(socket)['testComplete'][0].remove()

You could even loop through all the listeners attached and remove them.

for(var prop in getEventListeners(websocket))
{
    $(getEventListeners(websocket)[prop]).each(function() { this.remove()})
}

It's worth pointing out that although this works, it only works in Chrome at the moment.

cassepipe
  • 371
  • 6
  • 16
Tod
  • 2,070
  • 21
  • 27