0

I tried to make kind of object to work with my timer. The thing is when I have only bare functions (which are not in object) it is working. But When I put it inside object it doesnt work.

With this code I see only 00:01

When I used only the functions themselves it was working ok, I would like to have them in object cos I will have more functions in my code.

Thanks for help

$(document).ready(function() {
  var Timer = {
    TimerID: null,
    elapsed: 0,
    changeTimer: function() {
      this.TimerID = setInterval(this.timerTick(), 1000);
    },
    timerTick: function() {
      this.elapsed++;
      var minutes = Math.floor(this.elapsed / 60);
      var seconds = this.elapsed - (minutes * 60);
      if (minutes < 10) minutes = "0" + minutes;
      if (seconds < 10) seconds = "0" + seconds;
      $('.timer-html').text(minutes + ":" + seconds);
    },
    stopTimer: function() {
      clearInterval(this.TimerID);
    }
  };
  console.log(Timer);
  $(".timer").click(Timer.changeTimer());
  $(".stop-timer").click(Timer.stopTimer());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="javascript:;" class="timer">start clock</a>
<a href="javascript:;" class="stop-timer">stop clock</a>
<h1 class="timer-html">00:00</h1>

1
  • 2
    setInterval(this.timerTick(), 1000); Is wrong, it is executing timerTick once then passing the return value, which is undefined, into setInterval. Instead either pass timerTick in directly (without executing it) or wrap it in an annon function. Also be aware of context changes when using setInterval/settimeout. Either: setInterval(() => this.timerTick(), 1000); or setInterval(this.timerTick, 1000); Commented Jan 8, 2018 at 11:18

2 Answers 2

2

$(document).ready(function() {

    var Timer = {
        TimerID : null,
        elapsed : 0,

        changeTimer: function () {
           //here you need to send the delegate function without ()            //.. setInterval(this.timerTick
            //this.TimerID = setInterval(this.timerTick.bind(this), 1000);
            //arrow function variant
             this.TimerID = setInterval(()=>this.timerTick(), 1000);
        },

        timerTick: function ()
        {  
            this.elapsed++;
            var elapsed =  this.elapsed;
            var minutes = Math.floor(elapsed / 60);
            var seconds = elapsed - (minutes * 60);

            if (minutes < 10)
                minutes = "0" + minutes;

            if (seconds < 10)
                seconds = "0" + seconds;

            $('.timer-html').text(minutes + ":" + seconds);
        },

        stopTimer: function () {
           clearInterval(this.TimerID);
        }
    };

    console.log(Timer);
    //here you to keep the timer context, you can use arrow function
    //.. ()=> or .bind(Timer)
    $(".timer").click(()=> Timer.changeTimer());
    $(".stop-timer").click(()=> Timer.stopTimer());
    //.bind() variant
    // $(".timer").click(Timer.changeTimer.bind(Timer));
    // $(".stop-timer").click(Timer.stopTimer.bind(Timer));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<a href="javascript:;" class="timer">start clock</a>
<a href="javascript:;" class="stop-timer">stop clock</a>
<h1 class="timer-html">00:00</h1>

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks its working, btw I saw .bind is depracted. How can I change it for smh which is not depracted
where did you read is deprecated ? btw, I put new version which relies on ()=> ES6 sintax
As of jQuery 3.0, .bind() has been deprecated. It was superseded by the .on() method for attaching event handlers to a document since jQuery 1.7, so its use was already discouraged.
this are 2 different API what I uses is the native bind() function of JS not the bind() API of JQUERY, btw I suggest you to check out bind(), call(), apply(). These function can be handy in ES5, they have a new variant in ES6 as ()=> and ... (spread operator)
var stopWatch = { TimerID : null, startHours : parseInt(GetParams.getSearchParameters().hours), startMinutes : parseInt(GetParams.getSearchParameters().minutes), startSeconds : parseInt(GetParams.getSearchParameters().seconds), totalSeconds : this.startSeconds } btw why totalSeconds is undefined? How can I access the previous variables?
|
1

To post my comment as an answer (was as a bit silly leaving it as a comment when i believe it solves the issue).

setInterval(this.timerTick(), 1000); appears to be wrong.

It is executing timerTick once then passing the return value, which is undefined, into setInterval.

Instead either pass timerTick in directly (without executing it) or wrap it in an annon function.

Either: setInterval(() => this.timerTick(), 1000); or setInterval(this.timerTick, 1000);

Also be aware that setTimeout / setInterval will change the context (this) of the function it executes. The annon method will safeguard against that. However you could also bind the function before you pass it into setInterval.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.