I have been trying for hours remove event listener without any success.
Because of a test I have carried out I understood that the problem probably lies in listener reference.
Here is the code. I stripped and simplified everything for the clarity sake.
const COMPLETE = 'complete';
let dispatcher = new EventTarget;
class Template {
complete(e){
e.currentTarget.removeEventListener(COMPLETE, this.complete);
console.log('I run only once');
}
}
let child = new Template();
child.exe = function(){
dispatcher.addEventListener(COMPLETE, this.complete.bind(this));
}
child.exe();
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
Of course in console you can read three times "I run only once".
The test I did involved extra variable 'functionReference' where I store the listener reference. Then it works.
let functionReference
const COMPLETE = 'complete';
let dispatcher = new EventTarget;
class Template {
complete(e){
e.currentTarget.removeEventListener(COMPLETE, functionReference);
console.log('i run only once');
}
}
let child = new Template();
child.exe = function(){
functionReference = this.complete.bind(this);
dispatcher.addEventListener(COMPLETE, functionReference);
}
child.exe();
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
Now in console there is only once "I run only once".
What is happening? Why I can't remove that listener?
*****UPDATE / SOLUTION BELOW ***Many thanks to Teemu and amrender singh
Thank You amrender singh for explanation! And thank You Teemu for great idea and solution! Thank You so much for quick help! I haven't been stuck so much in years.
Below Teemu solution:
const COMPLETE = 'complete';
let dispatcher = new EventTarget;
class Template {
constructor(){
this.complete = (e)=>{
e.currentTarget.removeEventListener(COMPLETE, this.complete);
console.log('i run only once');
}
}
}
let child = new Template();
child.exe = function(){
dispatcher.addEventListener(COMPLETE, this.complete);
}
child.exe();
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
Alternatively a reference to the listener can be stored and passed as a variable.