0

I am trying to make my setTimeout function reusable. But whenever I pass the remainingTime value, It does not decrement.

console.log(remainingTime); repeatedly returns 99 rather than decrementing ie 98, 97.

Any ideas?

let remainingTimeToSolveQuiz = 100;
const timeRemainingEl = document.querySelector("#time-remaining");

function quizCountDown(remainingTime, elementToDisplayTime) {

  remainingTime--;
  console.log(remainingTime);

  if (remainingTime === 0) {
    // something
    clearTimeout(timer);
  }
  elementToDisplayTime.textContent = remainingTime;
}

let quizTimer = setInterval(quizCountDown, 1000, remainingTimeToSolveQuiz, timeRemainingEl);
<div>
Time: <span id="time-remaining"></span>
</div>
Simone Anthony
  • 524
  • 6
  • 15
  • 1
    Honestly, just debug the code. Put a breakpoint in `quizCountDown` and you'd see it's called with 100 every time it's called, because it's getting exactly the value of `remainingTimeToSolveQuiz` that you gave it in the first place. Note also that `clearTimeout(timer)` won't work because there is no variable `timer` in scope that represents a timer to clear. – Heretic Monkey Nov 26 '21 at 03:07

2 Answers2

1

You're passing in the initial value of remainingTimeToSolveQuiz into setInterval. This is passed by value, so it doesn't change with each loop.

So basically every time your quizCountDown function runs, it is using the initial value of 100 rather than the updated value.

Remove the remainingTimeToSolveQuiz passed into the interval and instead just use the real variable within your quizCountDown function.

Also make sure your quizTimer variable is initialized and that you reference it properly in clearTimeout.

let quizTimer;

function quizCountDown(elementToDisplayTime) {

  remainingTimeToSolveQuiz--;
  console.log(remainingTime);

  if (remainingTimeToSolveQuiz === 0) {
    // something
    clearTimeout(quizTimer);
  }
  elementToDisplayTime.textContent = remainingTimeToSolveQuiz;
}

quizTimer = setInterval(quizCountDown, 1000, timeRemainingEl);

As a side note, I really don't recommend using setInterval or setTimeout if you want to measure accurate time. It will always be an approximation.

If you set an interval for 1000ms, it will always be a couple of milliseconds off, which can add up to large inaccuracies over a longer period of time.

A more effective approach would be to use timestamps to calculate the elapsed time since a stored initial starting point.

skara9
  • 4,042
  • 1
  • 6
  • 21
1

Your setInterval is calling the function every one second. Every time it is called you are passing the same params, one of which is a value of 100. So every time your function is called, you are passing 100 and your function does what it is asked to do, subtract 1. That is why you see 99 repeat.

Solution: A global variable to keep track of the time:

let quizTime = 100; // global variable stores the quiz time

const timeRemainingEl = document.querySelector("#time-remaining");
let quizTimer;

function quizCountDown(elementToDisplayTime) {

  if (quizTime === 0) {
    // something
    clearTimeout(quizTimer);
  }
  elementToDisplayTime.textContent = quizTime;
  
  console.log(quizTime);
  quizTime--; // Calling this last starts your quiz timer with 100
}

quizTimer = setInterval(quizCountDown, 1000, timeRemainingEl);
<div>
Time: <span id="time-remaining"></span>
</div>

Also, it helps to call quizTime-- last. Because then your timer will show 100 initially.

Mush-A
  • 435
  • 3
  • 11