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
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.
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();
}