removeEventListener() should be called with a correct listener

  • BAD_REMOVE_EVENT_LISTENER
  • Error
  • Medium
  • No tags

This rule applies when removeEventListener() is called with a wrong listener.

The removeEventListener() method can only remove the exact function instance that was added at the addEventListener() call. So, nothing occurs in the following cases:

  1. When a newly created function is passed. This case is likely caused by a programmer's misunderstanding that if two functions have the same textual body, they will represent the same function instance. Also, it could result from the Function.prototype.bind() that always generates a new function instance.
  2. When the return value of addEventListener() is passed. Note that the return value of addEventListener()' is not the added listener function, but anundefined` value.

Unremoved listeners would cause a memory leak. To fix this problem, you should keep the reference of the added handler and use it as the argument of the removeEventListener().

Noncompliant Code Example

View with compliant examples side by side
// Example 1
export class Foo {
    update() {
        doUpdate(this);
    }
    addHandlers() {
        document.addEventListener("keydown", () => foo());
        document.addEventListener("click", this.update.bind(this));
    }
    removeHandlers() {
        document.removeEventListener("keydown", () => foo()); // BAD_REMOVE_EVENT_LISTENER alarm
        document.removeEventListener("click", this.update.bind(this)); // BAD_REMOVE_EVENT_LISTENER alarm
    }
}

// Example 2
export class Bar {
    update = () => {
        doUpdate(this);
    }
    init() {
        this.handler = document.addEventListener("click", this.update);
    }
    destroy() {
        document.removeEventListener("click", this.handler); // BAD_REMOVE_EVENT_LISTENER alarm
    }
}

Compliant Code Example

View with noncompliant examples side by side
// Example 1
export class Foo {
    keydownHandler() {
        foo();
    }
    update = () => {
        doUpdate(this);
    }
    addHandlers() {
        document.addEventListener("keydown", this.keydownHandler);
        document.addEventListener("click", this.update);
    }
    removeHandlers() {
        document.removeEventListener("keydown", this.keydownHandler);
        document.removeEventListener("click", this.update);
    }
}

// Example 2
export class Bar {
    update = () => {
        doUpdate(this);
    }
    init() {
        document.addEventListener("click", this.update);
    }
    destroy() {
        document.removeEventListener("click", this.update);
    }
}

Version

This rule was introduced in DeepScan 1.28.0.

See

Was this documentation helpful?