Delete the event handler in the handler itself

In short: I would like to bind the .bind result as an argument in my own call

var bound = foo.bind(this,bound); 

because I'm not sure how else to solve my problem.

Problem:

I have an element that depends on an array of other elements. When one of these elements is removed, I want to remove the dependent element and remove all listeners placed in the dependency.

I am trying to remove event handlers from other dependencies. I am trying to use bind, but since the handler function is the one that removes the listeners, I believe that I will have to bind the result of calling bind() in its own call as an argument. This, of course, does not work.

The following is a bind call that binds an unrelated version of the 'handler' as a parameter, and thus removeEventListener does not work, as it is a different copy of the function.

Question: can I use bind for this and / or how can I solve it otherwise?

Im uses eventemitter3 , but it should be the same for any event library.

 setHandlers(dependentItem,dependencies) { var handler = this.onDependencyRemoved; handler = handler.bind(this,dependentItem,dependencies,handler);//bind itself as third argument dependencies.forEach(dependency => { dependency.addEventListener("removed",handler); }); } onDependencyRemoved(dependentItem,dependencies,handler) { dependentItem.remove(); dependencies.forEach(dependency => { dependency.removeEventListener("removed",handler); }); } 

change

Full working example to run in nodejs:

 const EventEmitter = require('events'); //const EventEmitter = require('eventemitter3'); class MyEmitter extends EventEmitter { remove() { console.log("I'm being removed, this should happen only once"); } } var dependent = new MyEmitter(); var dependencies = [new MyEmitter(),new MyEmitter()]; var handler = (e) => removeHandler(dependencies,dependent,handler); dependencies.forEach(dependency => dependency.once('removed',handler)); var removeHandler = function(dependencies,dependent,handler) { //remove the dependent object because one of the dependencies was removed dependent.remove(); //remove the listeners from all of the dependencies dependencies.forEach(dependency => { console.log('before removing: '+dependency.listeners('removed').length); dependency.removeListener('removed',handler); console.log('after removing: '+dependency.listeners('removed').length); }); } //should remove the dependent object dependencies[0].emit("removed"); //should not do anything anymore since the listeners are removed dependencies[1].emit("removed"); 
+7
javascript function event-handling
source share
2 answers

You cannot do this using bind , but you can do it relatively easily using closure - either directly for the function to be bound, or in your own helper function similar to bind . It is as simple as

 const handler = (e) => this.onDependencyRemoved(dependentItem, dependencies, handler, e); 

I am not sure, however, why these two functions are methods of anything; they look pretty static. It might make sense to make them dependentItem methods, in which case arguments and even integer handler should not be stored in closure variables, but instance properties can be created that will be initialized in the constructor.

+7
source share

There are better ways to solve your problem that others have talked about. However, there is a more fundamental problem with the code:

 var bound = foo.bind(this,bound); 

The bound value in your code, at runtime, is undefined . This is the equivalent of just calling foo.bind(this) , which is probably not the one you want.

+6
source share

All Articles