-2

How can I use the window or document inside a JavaScript ES6 class

I tried the following code

Scenario #1:

class App {

    constructor() {
        console.info('App Initialized');

        document.addEventListener('DOMContentLoaded', function() {
           console.info('document Initialized');
           this.initializeView();
        }).bind(this);
    }

    initializeView() {
        console.info('View Initialized');
    }
}

const app = new App();

Note: I compiled the above code using gulp js

If I tried to call the class method inside the document.addEventListener, it throws the following error.

Uncaught TypeError: this.initializeView is not a function

So, I binded the this object to document .bind(this)

Scenario #2:

class App {

    constructor() {
        console.info('App Initialized');

        document.addEventListener('DOMContentLoaded', function() {
           console.info('document Initialized');
        }).bind(this);
    }
}

const app = new App();

If I tried without document.addEventListener, its working as expected in browser but if I tried with the document.addEventListener it throws an error

Uncaught TypeError: document.addEventListener(...) is undefined

enter image description here

Please assist me how to use the window or document inside the es6 class.

Scenarion #3:

class Booking {

    stepper = 1;

    constructor() {
        console.info('Booking Initialized');

        document.addEventListener('DOMContentLoaded', function() {
            console.log('document Initialized')
        });
    }
}

I'm getting the following exception

Uncaught ReferenceError: options is not defined

The referred solution is not has any relevance to the Question's subject matter How to access the correct `this` inside a callback

I'm not sure how the expertise people giving the above link as a solution.

B.Balamanigandan
  • 4,713
  • 11
  • 68
  • 130
  • `document.addEventListener(...).bind(this)` makes no sense. Remove the `.bind(this)`. – CertainPerformance Oct 13 '21 at 03:29
  • @CertainPerformance - I elaborated the question and also mentioned that why I used the `.bind(this)` please assist me how to run the code without any exception. – B.Balamanigandan Oct 13 '21 at 03:35
  • 2
    Then this is a duplicate of https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback – CertainPerformance Oct 13 '21 at 03:36
  • @CertainPerformance - Here my question is how to use the `document` or `window` inside a class. I don't have confusion on the usage of `this` keyword. – B.Balamanigandan Oct 13 '21 at 03:38
  • It looks like you do, because you're using `.bind` incorrectly, in an attempt to access the `this` inside. tl;dr use an arrow function instead and remove the `.bind` – CertainPerformance Oct 13 '21 at 03:39
  • @CertainPerformance - Here the question's subject matter is **how to use the global object `window` or `document` inside the es6 class**. If I have mistakes in the code please correct and try to give solution for the subject matter. Now the discussion turned into a wrong dirction. – B.Balamanigandan Oct 13 '21 at 03:41
  • You really don't have to do anything at all in order to use them. `someMethod() { window.addEventListener('click', someFn)` will work just fine, for example. They can be used inside just like they can be used outside. – CertainPerformance Oct 13 '21 at 03:42
  • @CertainPerformance - Please if you have any concern on the usage of .bind, mentioned it in the answer section as a Note. Also, I attached the browser console error for your reference. Please try the above code before giving strong suggestions. Please. – B.Balamanigandan Oct 13 '21 at 03:46
  • The error is caused by your incorrect use of `.bind(this)` on the call of `addEventListener`. Remove it, and use an arrow function instead – CertainPerformance Oct 13 '21 at 03:47
  • @CertainPerformance - I added one more scenario #3 as per your opinion in the question. Please check. – B.Balamanigandan Oct 13 '21 at 03:53
  • You have never defined an identifier named `options`, so yeah, it'll throw `Uncaught ReferenceError: options is not defined`... it's pretty self-explanatory... – CertainPerformance Oct 13 '21 at 03:54
  • @CertainPerformance - as a expertise you know, but I don't know. Could you please assist me. – B.Balamanigandan Oct 13 '21 at 03:55

1 Answers1

1

You don't want to use a function(){} for your event handling, because regular functions derive this from the context at runtime, and that context is not your object, but the global context. Using the ancient bind() function (if done right) gets around that, but so does modern arrow function syntax, so use that instead.

   constructor() {
        console.info('App Initialized');

        document.addEventListener('DOMContentLoaded', () => {
           console.info('document Initialized');
           this.initializeView();
        });
    }

Done.

However, this is silly code and we don't have to do this at all: load your script in the <head> element, as <script src="..." async defer></script>, using the defer attribute so that your script doesn't run until the DOM is ready for queries. It's been around for about a decade now, no need for that event listening; just run the code that needs to run.

   constructor() {
        console.info('App Initialized');
        this.initializeView();
    }
Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153