At the moment, I’m using angularjs with phoenix and I want to know how can I unbind custom channel events.
In Angularjs, one way would be like this.
var unbindHandler = $scope.$on("channel_event", channelFunction); // returns a deregistration function
.... later down the line
unbindHandler() // event is unbinded
unbindHandler = null
When I try to do the same thing with with the channel object.
var unbindHandler = channel.on("new_message", message => {
... code
})
and call it
unbindHandler()
I get an error saying that unbindHandler is not a function because it is undefined. Because of this I have to assume that channel.on doesn’t return a deregistration function for me to use so I can unbind when I’m done. What can I do?
I’ve tried to leave the channel(channel.leave()) hoping that it would automatically unbind but it still doesn’t.
It returns a ref:
var ref = channel.on("new_message", message => { ... });
channel.off("new_message", ref);
You could create a wrapper function:
function channelFunctionFactory(channel) {
return function(event, callback) {
var ref = channel.on(event, callback);
return function() {
channel.off(event, ref);
}
}
}
var channelFunction = channelFunctionFactory(channel);
var unbindHandler = channelFunction("new_message", message => { ... });
unbindHandler();
OK, so this is untested. I don’t know if it will work, but it gives you what you want (I think).
Thanks for the reply, but at least with angularjs, I don’t think it returns a ref.
To verify I did this
var channel = socket.channel("lobby", {});
console.log(channel.on("new_message", () => {
console.log("Hello");
})); // This prints out undefined
console.log(channel) // Yet it still says that it binded "new_message".
So is there any other way to get a handler or ref to the event?
Ah! I know what’s wrong.
It looks like the ref logic is only available in master right now.
You can do this:
function channelFunctionFactory(channel) {
return function(event, callback) {
channel.on(event, callback);
return function() {
channel.off(event);
}
}
}
var channelFunction = channelFunctionFactory(channel);
var unbindHandler = channelFunction("new_message", message => { ... });
unbindHandler();
Unfortunately it means you can’t bind to the same event multiple times. You could also try getting the updated phoenix.js from master.
1 Like
Thanks, that worked. I figured I was only able to bind to only one event at a time considering that when I joined a different channel, the number of bindings for each channel object was off. Much appreciated.
Though I have a question before I put this topic to rest.
If I do this
var channel = socket.channel("lobby", {});
Down the line I bind some events to that channel object and then I do this without unbinding the events
var channel = socket.channel("room", {});
Would it cause a memory leak for not calling channel.off on the previous channel object and initializing it with a new one? My intuition says yes but I’m not sure.
If not, then is there any point in unbinding in my case?