Reputation: 23
I am working on a HTML customelement, but when I run it in the browser, I get a very interesting error. This is the code:
class clock extends HTMLElement {
constructor() {
super()
this.time = new Date(this.getAttribute('time'));
this.span = document.createElement('span')
this.appendChild(this.span)
}
Timer() {
let Now = this.time;
let Seconds = Now.getSeconds();
let Minutes = Now.getMinutes();
let Hours = Now.getHours();
Minutes = Minutes < 10 ? "0" + Minutes : Minutes;
document.getElementById("digitalClock").textContent = Hours + ":" + Minutes;
}
connectedCallback(){
this.span.innerHTML = `...<span id="digitalClock"></span>`;
this.Timer();
this.myClockTimer = setInterval(this.Timer, 5000);
}
disconnectedCallback(){
clearInterval(this.myClockTimer);
}
}
customElements.define('worktime-clock', clock)
When I run this, the Timer function runs well when calling with this.Timer() in the connectedCallback function, but one line after, when it gets into a cycle, it says that Now is undefined in Timer function. It seems like there is a problem about calling it in setinterval, however, the function is definitely running again and again as expected. Does someone know what is the problem?
Upvotes: 0
Views: 533
Reputation: 21193
Or an arrow function
<script>
customElements.define('worktime-clock', class extends HTMLElement {
updateTime() {
let Now = new Date();
const pad = x => String(x).padStart(2,'0');
const H = pad(Now.getHours());
const M = pad(Now.getMinutes());
const S = pad(Now.getSeconds());
this.innerHTML = `${H}:${M}:${S}`;
}
connectedCallback() {
this.myClockTimer = setInterval(() => {
this.updateTime();
}, 1e3);
}
})
</script>
<worktime-clock>21:22:23</worktime-clock>
<script>
customElements.define('worktime-clock', class extends HTMLElement {
connectedCallback() {
setInterval(() => {
this.innerHTML = new Date().toString().split` `[4];
}, 1e3);
}
})
</script>
<worktime-clock>21:22:23</worktime-clock>
Upvotes: 1
Reputation: 3494
You lose the correct this
context by passing the Timer function as a callback. As a result this
(within the callback) now points to window
instead. You can use bind
to set the this-context:
this.myClockTimer = setInterval(this.Timer.bind(this), 5000);
This accomplishes the same thing:
var that = this;
this.myClockTimer = setInterval(function() { that.Timer(); }, 5000);
Another alternative:
this.myClockTimer = setInterval(function() { this.Timer(); }.bind(this), 5000);
Upvotes: 2