Patrik CK
Patrik CK

Reputation: 25

addClass jQuery throw

this is the start of a larger project but I'm running into an error as I test the basics on the frontend. The error is as follows

Uncaught TypeError: Cannot read property 'addClass' of undefined
    at HTMLDivElement.openOverlay (live-search.js?ver=1.0:20)
    at HTMLDivElement.dispatch (jquery.js?ver=1.12.4-wp:3)
    at HTMLDivElement.r.handle (jquery.js?ver=1.12.4-wp:3)

This is the code I have so far, for the moment I'm just testing the trigger to open and close an overlay.

(function($) {

class Search {
    constructor() {
        this.openButton = $("#search-icon-btn");
        this.closebutton = $(".search-overlay__close");
        this.searchOverlay = $(".search-overlay");
        this.events();
    }

    events() {
        this.openButton.on("click", this.openOverlay);
        this.closebutton.on("click", this.closeOverlay);
    }

    openOverlay() {
        this.searchOverlay.addClass("search-overlay--active");
    }

    closeOverlay() {
        this.searchOverlay.removeClass("search-overlay--active");
    }
}

var liveSearch = new Search();

})(jQuery);

Any help would be much appreciated!

Upvotes: 1

Views: 50

Answers (1)

Kei
Kei

Reputation: 1026

When openOverlay is called as an event handler, "this" gets overridden. In this case, I believe it would refer to the openButton (the sender) rather than the Search instance. Thus, this.searchOverlay would be undefined.

There are several ways to get around this. You could use the bind method to explicitly bind "this."

events() {
    this.openButton.on("click", this.openOverlay.bind(this));
    this.closebutton.on("click", this.closeOverlay.bind(this);
}

Alternatively, you could set up openOverlay and closeOverlay to receive a reference to the Search instance.

events() {
    this.openButton.on("click", () => this.openOverlay(this));
    this.closebutton.on("click", () => this.closeOverlay(this));
}

openOverlay(self) {
    self.searchOverlay.addClass("search-overlay--active");
}

closeOverlay(self) {
    self.searchOverlay.removeClass("search-overlay--active");
}

Further reference: https://stackoverflow.com/a/20279485/11981207

Upvotes: 1

Related Questions