Reputation:
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.
Upvotes: 83
Views: 86750
Reputation: 43
Old question, but answers here helped me. Below is a stripped version of my implementation.
Angular: 15.2.0
socket.io-client: 4.6.1
Chrome: Version 118.0.5993.118 (Official Build) (64-bit)
What I did was create a Map in my websocket service. I use it to store the callback function, with the event name as key.
eventHandlerMapper: Map<string, (response: any) => void> = new Map();
My listen() function looks like so: (Returning an Observable so my subscriber can handle the payload)
listen(eventName: string): Observable<any> {
return new Observable((subscriber) => {
const handler = (data: any) => subscriber.next(data);
// register handler to socket for this event name
this.socket.on(eventName, handler);
// store for unlistening
this.eventHandlerMapper.set(eventName, handler);
});
}
To unlisten, I simply do this:
unlisten(eventName: string): void {
this.socket.off(eventName, this.eventHandlerMapper.get(eventName));
}
By passing the ORIGINAL handler back into this.socket.off(), it unregisters the handler from the socket for the specified event name.
Referencing Socket.io Client API document:
I then checked the efficacy of my implementation by logging out my socket object and checking its list of registered callback functions, before and after listening/unlistening.
Upvotes: 0
Reputation: 2524
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.
Upvotes: 0
Reputation: 1692
//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
Upvotes: 141
Reputation: 11588
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);
}
Upvotes: 54