-1

So I was trying to write some javascript to countdown and then submit the form when the countdown is finished. This is the JS I found online and tried to implement:

 var seconds = 300;

 function secondPassed() {
   var minutes = Math.round((seconds - 30) / 60),
     remainingSeconds = seconds % 60;

   if (remainingSeconds < 10) {
     remainingSeconds = "0" + remainingSeconds;
   }

   document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
   if (seconds == 0) {
     clearInterval(countdownTimer);
     document.qForm.submit();
   } else {
     seconds--;
   }
 }
 var countdownTimer = setInterval('secondPassed()', 1000);

Here it is implemented: https://jsfiddle.net/spadez/9p9o4k6s/1/

The error says: secondPassed is not defined but I'm not sure why that is. Could anyone please explain where I have gone wrong?

Jimmy
  • 12,087
  • 28
  • 102
  • 192
  • 3
    Change it to `setInterval(secondPassed, 1000);` Please see [**setInterval Documentation**](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval) for more details – Nope Oct 10 '17 at 08:46
  • 1
    I know this possible duplicate of [**How do I correctly use setInterval and clearInterval to switch between two different functions?**](https://stackoverflow.com/questions/10485385/how-do-i-correctly-use-setinterval-and-clearinterval-to-switch-between-two-diffe) is asking for more than just clear and set interval but it shows how to use it correctly by no specifying the function reference as a string. – Nope Oct 10 '17 at 08:48

3 Answers3

1

There is an error in last line of your code. Change that line to this'

var countdownTimer = setInterval(secondPassed, 1000);

Here is the updated fiddle. https://jsfiddle.net/9p9o4k6s/3/

codeslayer1
  • 3,666
  • 3
  • 17
  • 13
  • Please see https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval. There is no error there, `setInterval` can take code in stringas first arg – Andrzej Smyk Oct 10 '17 at 08:51
1

When you pass a function call as a string to setInterval like that, the function you're calling must be in the global scope. Your function secondPassed is wrapped by the jsFiddle onload wrapper and so it is not in the global scope.

To demonstrate this, if you did window.secondPassed = secondPassed; to put it in the global scope, your existing code would work.

The proper solution is to pass the function object as the argument instead of a string:

var countdownTimer = setInterval(secondPassed, 1000);

Note there are no parenthesis () when used in this way.

MrCode
  • 63,975
  • 10
  • 90
  • 112
1

For me both ways of calling setInterval work well with SO snippet. I think bug can be jsfiddle specific as it seems it accepts only the first form of setInterval, which takes function and interval, not code string to execute and delay (https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval). If you want to keep using fiddle you will have to change last line to:

var countdownTimer = setInterval(secondPassed, 1000);

         var seconds = 300;

         function secondPassed() {
           var minutes = Math.round((seconds - 30) / 60),
             remainingSeconds = seconds % 60;

           if (remainingSeconds < 10) {
             remainingSeconds = "0" + remainingSeconds;
           }

           document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
           if (seconds == 0) {
             clearInterval(countdownTimer);
             document.qForm.submit();
           } else {
             seconds--;
           }
         }
         var countdownTimer = setInterval('secondPassed()', 1000);
body {
  background-color: #eee;
}

canvas {}

time {color: red; float: right;}

.active {color: green; font-size: 12px; font-weight: bold;}
  <h3>Question 1 of 20<time id="countdown">5:00</time></h3>
  <form name="qForm">
    <input type="radio"> 219
    <input type="submit" value="Submit">
  </form>
Andrzej Smyk
  • 1,684
  • 11
  • 21