I have following html code
<html lang="en">
<body>
<div id="placeholder"></div>
<script type="module">
import { WriteReview } from "./src/script.js"
var inputElement = new WriteReview(document.getElementById("placeholder"));
inputElement.render();
</script>
</body>
</html>
In script.js have following code
export class WriteReview{
constructor(element){
this.rating ="5"
this.element=element;
}
setChange(){
this.rating = "3";
}
render(){
console.log("inside render");
this.element.innerHTML = `<input type="button" onclick="this.setChange()" value ="Click here" />`
}
}
When I click the button, browser reports an error "TypeError: this.setChange is not a function". Why I can't access the function setChange() from my index.html, how to resolve this issue. Issue URL: https://playcode.io/1532407
There's a couple of problems here.
First and foremost, within an onclick
attribute, this
refers to the element itself which obviously does not have a setChange()
method.
Secondly, you won't be able to set the click handler to your WriteReview
instance method because anything referred to in an onclick
attribute must be present in the global scope.
Instead, create an element dynamically and attach an event listener, using an arrow function to keep lexical scope within the class instance.
render () {
const input = Object.assign(document.createElement("input"), {
type: "button",
value: "Click here",
});
input.addEventListener("click", (e) => {
this.setChange();
});
this.element.append(input);
}
Here's a demo showing it working...
class WriteReview {
constructor(element) {
this.rating = "5"
this.element = element;
}
setChange() {
console.log("WriteReview#setChange called");
this.rating = "3";
}
render() {
const input = Object.assign(document.createElement("input"), {
type: "button",
value: "Click here",
});
input.addEventListener("click", (e) => {
console.log("[before] rating:", this.rating);
this.setChange();
console.log("[after] rating:", this.rating);
});
this.element.append(input);
}
}
var inputElement = new WriteReview(document.getElementById("placeholder"));
inputElement.render();
<div id="placeholder"></div>