Displaying live time on client

Hello,

What is the best way to display the live time on the client side? I tried

    this.Date = new ReactiveVar()
    this.setDate = ()=>{
        this.Date.set(new Date())
        setTimeout(this.setDate(), 1000)
    }
    this.setDate()

But get a maximum stack exceeded error.

I want the user to be able to clock in and out of working and set their project. I want to display the current time that will be entered if the click on log in/out button.

Whats the best way to accomplish?

ddd = new ReactiveVar()
setDate = ()=>{
	ddd.set(Date())
	console.log(ddd.get())
	Meteor.setTimeout(()=>{setDate()}, 1000)
}
setDate()
1 Like

stanps solution is correct, but I’d like to explain why.

setTimeout(this.setDate(), 1000)

On this line you are running the function this.setDate() and passing the result to setTimeout. This is causing your stack overflow because that function contains this line which calls itself, causing an infinite loop.
What you want is to pass a function to setTimeout, which it will execute later. Exactly as shown in stanp’s solution Meteor.setTimeout(() => { setDate() }, 1000)

The reason we create a new arrow function instead of just passing this.setDate is so we keep the this binding the same. Otherwise you won’t be able to access this.date in the function after it’s run by the setTimeout.


Alternatively you can skip the recursion and just use a setInterval:

this.Date = new ReactiveVar()
    this.interval = setInterval(() => {
        this.Date.set(new Date())
    }, 1000);

And to finish it off, you want to stop the interval when the template is destroyed:

Template.example.onCreated(function () {
    this.Date = new ReactiveVar()
    this.interval = setInterval(() => {
        this.Date.set(new Date())
    }, 1000);
});
Template.example.onDestroyed(function () {
    clearInterval(this.interval);
});
2 Likes

I usually use Meteor.setInterval.

1 Like

And I forgot to mention, the interval is preferable way to do it, because you can kill it on onDestroy, otherwise timeout will continue working in the background