skip to Main Content

so on Shopify store i’m trying to do a countdown timer, but when it hits 0 it should write 0, instead sometimes it writes NaN and sometimes it works and writes 0.
Does anyone know what is wrong?
Here is the code:

var tenMinutesLater = new Date();
var theTimerSet = new Date();


var myTimer = localStorage.getItem("myCountDown");
console.log(myTimer);
if (myTimer === null) {
  tenMinutesLater.setMinutes(tenMinutesLater.getMinutes() + 10);
  localStorage.setItem("myCountDown", tenMinutesLater);
  theTimerSet = tenMinutesLater.getTime();
} else {
  theTimerSet = new Date(myTimer).getTime();
}


var x = setInterval(function() {

  var now = new Date().getTime();

  var distance = theTimerSet - now;

  var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
  var seconds = Math.floor((distance % (1000 * 60)) / 1000);

  document.getElementById("the-timer").innerHTML = minutes + "m " + seconds + "s ";

  if (distance < 0) {
    clearInterval(x);
    document.getElementById("the-timer").innerHTML = "0";
  }
}, 1000);
<div class="timer" id="the-main-timer">
  Checkout within the next <em><span class="the-timer" id="the-timer"></span> minutes</em> to avoid losing your order.
</div>

4

Answers


  1. Chosen as BEST ANSWER

    This solved the problem form me, changing this:

    if (myTimer === null) {...
    

    to this:

    if( myTimer === null || myTimer == 'null'){
    

  2. This might be a solution, since the time should be shown only if distance is bigger than 1000, since distance is in ms, not in s.

    
      if (distance < 1000) {
        clearInterval(x);
        document.getElementById("the-timer").innerHTML = "0";
      }else{
    document.getElementById("the-timer").innerHTML = minutes + "m " + seconds + "s ";
    }
    
    Login or Signup to reply.
  3. I think found it, the value does not exist in localstorage.

    Where myTimer is undefined and with that undefined === null will be false.

    var myTimer = localStorage.getItem("myCountDown");  // -> undefined
    

    Then here we are creating Date with undefined and getting time where the result is NaN

    var theTimerSet = new Date(myTimer).getTime(); // -> NaN
    

    Then when NaN – [some number] will be undefined

    var distance = theTimerSet - now; // -> undefined
    

    Where again Math.floor of undefined is NaN

    var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); // -> NaN
    var seconds = Math.floor((distance % (1000 * 60)) / 1000); // -> NaN
    

    And this will show you NaN in your app.

    Login or Signup to reply.
  4. I cannot reproduce your NaN error.
    In my opinion this must have come from when retrieving the date saved in the LocalStorage with a string / number conflict.

    putting a date in local storage is not useful, you just need to keep its .getTime() value, since you have to redo this comparison every cycle.

    you also use 2 variables (tenMinutesLater and theTimerSet) for the same thing, which may be the source of your problem as well

    So I rewrote your code…
    remarks :
    — I can’t leave a variable named ‘X’ in my code.
    — I use the Whitesmiths style (please respect it, and yes I have my own beautifier for that)

    const 
      OneSec     = 1000
    , OneMin      = OneSec * 60
    , OneHour      = OneMin * 60
    , theTimer      = document.getElementById('the-timer')
    , lsName         = 'myCountDown'
    , lsValue         = localStorage.getItem(lsName) 
    , tenMinutesTarget = lsValue ? parseInt(lsValue) : new Date().getTime() + 10 * OneMin
      ;
    if (!lsValue) localStorage.setItem(lsName, tenMinutesTarget)
      ;
    let intvlRef = setInterval(()=>
      {
      let
        deltaTime = tenMinutesTarget - new Date().getTime()
      , minutes   = Math.floor((deltaTime % OneHour) / OneMin )
      , seconds   = Math.floor((deltaTime % OneMin) / OneSec  )
        ;
      theTimer.textContent = (deltaTime > 0) ? `${minutes}m ${seconds}s ` : '0 ';
    
      if (deltaTime < 0)
        {
        clearInterval(intvlRef)
        // localStorage.removeItem(lsName)  // ?
        }
      }, 250) 
    
    
    <div class="timer" id="the-main-timer">
      Checkout within the next
      <em>
        <span class="the-timer" id="the-timer"></span>
        minutes
      </em>
      to avoid losing your order.
    </div>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search