0

I am green with .js, I got some elements to be improved not in my application and I am unable to cope with removing the event.

Events was added in this way:

this.searchByNameElement.addEventListener("keyup", this.searchByNameElementOnKeyUp.bind(this), true);

but when I try after it remove in this way:

this.searchByNameElement.removeEventListener("keyup", this.searchByNameElementOnKeyUp, true);

it dont work. If I understand correctly how .bind(this) works, it create anonymous event and therefore cannot be deleted.

But when I remove .bind(this) the value off all properties this are null and method are undefined in for exaple this method:

searchByNameElementOnKeyUp() {
    clearTimeout(this.searchNameTimeout);

    // Make a new timeout set to go off in 800ms
    this.searchNameTimeout = setTimeout(async () => {
        await this.reloadDatabaseItems();
    }, 500);    
}

Can someone tell me how can I have value in this in method searchByNameElementOnKeyUp and be able to remove events?

Full class:

export class SubelementsDialog extends Dialog {
_this = null;
/**
 * Creates a subelements dialog from the specified dialog element.
 * @param {HTMLElement} dialogElement Element containing the dialog.
 */
constructor(dialogElement) {
    super();
    this.dialogElement = dialogElement;
    this.type = 0;
    this.typeName = 0;
    /** @type {SubelementsDialogElement[]} */
    this.selectedItems = [];

    /** @type {SubelementsDialogElementButton[]} */
    this.databaseElementsButtons = [];

    /** @type {string[]} */
    this.selectedPhotos = [];

    var databaseElementsContainer = dialogElement.querySelector(".set-parts-generate-partial");

    if (!(databaseElementsContainer instanceof HTMLElement))
        throw "Cannot find database elements container with class 'set-parts-generate-partial;";

    this.databaseElementsContainer = databaseElementsContainer;

    var selectedElementsContainer = dialogElement.querySelector("#set-parts-elements-choosen-table");

    if (!(selectedElementsContainer instanceof HTMLElement))
        throw "Cannot find database elements container with class 'set-parts-elements-choosen-table'";

    this.selectedElementsContainer = selectedElementsContainer;

    var searchByNameElement = dialogElement.querySelector(".set-parts-search");

    if (!(searchByNameElement instanceof HTMLInputElement))
        throw "Cannot find search input with class 'set-parts-search'";

    this.searchByNameElement = searchByNameElement;

    this.searchByNameElement.addEventListener("keyup", this.searchByNameElementOnKeyUp, true);

    const searchByIndexElement = document.querySelector(".set-parts-search-index");

    if (!(searchByIndexElement instanceof HTMLInputElement))
        throw "Cannot find index input with class 'set-parts-search-index'";

    this.searchByIndexElement = searchByIndexElement;

    this.searchByIndexElement.addEventListener("keyup", this.searchByIndexElementOnKeyUp.bind(this), true);


    const searchByDevIndexElement = document.querySelector(".set-parts-search-devindex");

    if (!(searchByDevIndexElement instanceof HTMLInputElement))
        throw "Cannot find devindex input with class 'set-parts-search-devindex'";

    this.searchByDevIndexElement = searchByDevIndexElement;

    this.searchByDevIndexElement.addEventListener("keyup", this.searchByDevIndexElementOnKeyUp.bind(this), true);



    var exitElement = document.querySelector(".set-parts-exit-button");

    if (!(exitElement instanceof HTMLElement))
        throw "Cannot find exit element with class 'set-parts-exit-button'";

    this.exitElement = exitElement;

    this.exitElement.addEventListener("click", this.exitElementOnClick.bind(this), true);
}

/**
 * @param {number} type
 */
setType(type) {
    this.type = 0;
    this.type = type;

}

getType() {
    return this.type;
}

/**
 * @param {SubelementsDialogElement[]} items 
 */
setSelectedItems(items) {
    if (!items)
        items = [];

    this.selectedItems = items;
    this.selectedItemsChanged();
}

getSelectedItems() {
    return this.selectedItems;
}

async show() {
    await this.reloadDatabaseItems();
    this.dialogElement.style.visibility = "visible";
}

close() {
    this.dialogElement.style.visibility = "hidden";
    //this.RemoveEvents();
    //this.reloadDatabaseItems();
    super.close();
}
RemoveEvents() {
    this.searchByNameElement.removeEventListener("keyup", this.searchByNameElementOnKeyUp, true);
    this.searchByIndexElement.removeEventListener("keyup", this.searchByIndexElementOnKeyUp, true);
    this.searchByDevIndexElement.removeEventListener("keyup", this.searchByDevIndexElementOnKeyUp, true);
}

exitElementOnClick() {
    //this.searchByNameElement.value = "";
    //this.searchByIndexElement.value = "";
    //this.searchByDevIndexElement.value = "";
    var typ = types[this.getType()];
    if (this.dialogElement.textContent?.includes(typ)) {
        this.reloadDatabaseItems();
    }
    this.close();
}

/**
 * @param {SubelementsDialogElement} databaseElement 
 */
select(databaseElement) {
    var found = this.selectedItems.find(el => el.id == databaseElement.id);

    if (!found) {
        if (databaseElement.quantity == null || databaseElement.quantity == 'undefined')
            databaseElement.quantity = 1;
        this.selectedItems.push(databaseElement);
        this.selectedItemsChanged();
    }
}

/**
 * @param {SubelementsDialogElement} databaseElement 
 */
deselect(databaseElement) {
    var found = this.selectedItems.findIndex(el => el.id == databaseElement.id);

    if (found >= 0) {
        this.selectedItems.splice(found, 1);
        this.selectedItemsChanged();
    }
}

/**
 * @param {number} databaseElementId 
 */
isSelected(databaseElementId) {
    return !!this.selectedItems.find(el => el.id == databaseElementId);
}

searchByNameElementOnKeyUp() {
    clearTimeout(this.searchNameTimeout);

    // Make a new timeout set to go off in 800ms
    this.searchNameTimeout = setTimeout(async () => {
        await this.reloadDatabaseItems();
    }, 500);    
}
searchByDevIndexElementOnKeyUp() {
        clearTimeout(this.searchByDevIndexTimeout);

        // Make a new timeout set to go off in 800ms
        this.searchByDevIndexTimeout = setTimeout(async () => {
            await this.reloadDatabaseItems();
        }, 500);
}
searchByIndexElementOnKeyUp() {
        clearTimeout(this.searchByIndexTimeout);

        // Make a new timeout set to go off in 800ms
        this.searchByIndexTimeout = setTimeout(async () => {
            await this.reloadDatabaseItems();
        }, 500);
}

selectedItemsChanged() {
 //...
}

async reloadDatabaseItems() {
 //...      
}
}
Silny ToJa
  • 1,815
  • 1
  • 6
  • 20
  • See also https://stackoverflow.com/questions/66777301/remove-eventlistener-defined-in-a-class/66778579 – Teemu May 20 '21 at 11:07
  • I solved this by assigning all properties with bind(this) to the variable and then passing it to add and remove eventListener. – Silny ToJa May 20 '21 at 11:10
  • 1
    You can do that too, only that with my solution you can avoid the use of the external variables, everything is wrapped within the class. – Teemu May 20 '21 at 11:19

0 Answers0