0

Hi im trying to make a clock Class that when I call it, it will print in terminal current time every 1 second. The first output is printed correctly but the problem is when the loop of interval go to second, my render method cannot read this. template. I tried to console.log it and the result is undefined. can someone help with my code? thank you

class Clock {
    constructor({ template }) {
        this.template = template
    }
    render() {
        console.log(this.template)
        let date = new Date()
        let hours = date.getHours();
        if (hours < 10) hours = '0' + hours;

        let mins = date.getMinutes();
        if (mins < 10) mins = '0' + mins;

        let secs = date.getSeconds();
        if (secs < 10) secs = '0' + secs;

        let output = this.template
            .replace('h', hours)
            .replace('m', mins)
            .replace('s', secs);

        console.log(output);
    }

    stop() {
        clearInterval(this.timer)
    }

    start() {
        this.render()
        this.timer = setInterval(this.render, 1000)
    }
}
let clock = new Clock({ template: 'h:m:s' });
clock.start(); 
Charlie
  • 22,886
  • 11
  • 59
  • 90
  • `this.render.bind(this)` – user120242 Jun 23 '20 at 05:43
  • The issue is that you're losing the `this` context when you pass the method as a function reference here: `setInterval(this.render, 1000)`. You can use an arrow function instead `setInterval(() => this.render, 1000)` which will alleviate the issue. Another option is `setInterval(this.render.bind(this), 1000)` (I personally don't like it because it repeats `this`) or you can make the method itself automatically bound by changhing the declaration to `render = () => {` – VLAZ Jun 23 '20 at 05:44
  • thank you everyone, my code is working now =) – Singgit Bramantha Jun 23 '20 at 06:13

1 Answers1

0

You need to bind This to the function like this.

this.timer = setInterval(this.render.bind(this), 1000)
mgm793
  • 1,968
  • 15
  • 23