Pomodoro Timer; tons of little issues are killing my soul

Pomodoro Timer; tons of little issues are killing my soul
0

#1

TLDR: tired and fatigued and needing a little help to cross the line. :slight_smile:

Struggling to understand what’s going wrong on this. Used the Chrome console to try understand what fell apart. I was testing it all the way through and now it’s totally broken in the last mile; which has me totally baffled.

Issues I’m having are from pedestrian on up; seems I’ve created a cascade of failure here.

  1. I can’t seem to get the value from my two .querySelector’s, which I’m baffled. They are pulling from the bottom HTML I’ve included to assist you in making sense of the code.
  2. Then I can’t seem to figure out how to call my killPomodoro function. I even assigned the function to a global. I have some ideas on how I can change it some more to play with scope and get what I want, but I’m running low on ideas; I’ve tried lots of tweaks to this code.
  3. I still need to wrap the clock function in a setInterval function, but I can’t finish it without solving some of these (scope?) issues and while they may change when I make that last step I’d like to understand why it’s not working as intended now :frowning:

Your assistance is very much appreciated.
PLEASE don’t tell me your super awesome way of doing the Pomodoro Timer your way, which I’m sure is amazing, just please assist me to get MY code working.

Thank you!!

let minInputWork = document.querySelector('#work').value
let minInputBreak = document.querySelector('#break').value
let clockTimeRemaining;
let breakTimeRemaining;
let killPomodoro;

const stopClock = document.querySelector('#countdown')
const startClock = document.querySelector('.startBtn')

startClock.addEventListener('click', clock)
stopClock.addEventListener('click', killPomodoro)


function clock (minInputWork, minInputBreak){

  const endDate = function getEndDate (startDate, minInputWork){
    return startDate + minInputWork * 60 * 1000}

  const breakEndDate = function getEndBreakDate(startDate, minInputWork, minInputBreak){
    return startDate + (minInputWork + minInputBreak ) * 60 * 1000}//Convert to millies

  const startDate = Date.now()
  console.log('timer Counter', minInputWork);
  startWorking()  // Call startWorking function
  function startWorking (){
    const timer =
      setInterval(()=>{
        clockTimeRemaining = Math.floor((endDate(startDate, minInputWork) - Date.now())/1000);
        console.log('timer Counter', clockTimeRemaining);

        if(clockTimeRemaining <= 0){
          clearInterval(timer)
          console.log('End Timer');
          startBreak()
        }
      },1000)
  }
  function startBreak (){
    const breakTimer =
      setInterval(()=>{  // This one
        breakTimeRemaining = Math.floor((breakEndDate(startDate, minInputWork, minInputBreak) - Date.now())/1000);
          console.log('break Counter', breakTimeRemaining);
          if(breakTimeRemaining < 0){
            clearInterval(breakTimer)
            console.log('End Break');
            clock (minInputWork, minInputBreak)
          }
      },1000)
  }
  killPomodoro =
    function killClock (timer, breakTimer){
      return clearInterval(timer), clearInterval(breakTimer)
    }
}

----- HTML Below -----

  <div id="container">
    <h1 class="title startBtn">FreeCodeCamp Pomodoro</h1>
    <div id="box">
      <input id="work" type="number"/>
      <input id="break" type="number"/>
    </div>
    <div id="activity">
      <h1 class="title">Countdown</h1>
      <div id="countdown"></div>
    </div>
  </div>

#2

Is this all of the code (HTML and JavaScript) you are using for your project? If not, can you provide a url to all your code (i.e. Codepen, JSFiddle, etc…)?


#3

The only thing missing is the tag and the body elements that make up html5

I’m writing it in VSCode and while I have the css lipstick on codepen, there is no brains on codepen; I’m just focused on the js interaction with the basic html and what you see is exactly what I’m testing. So it may feel like things are missing because it looks bad, but there is no difference between what you have and what i have; there is no css on my copy either.

Thank you for asking and for looking :slight_smile:


#4

One big problem with your solution is the clock function. You have two parameters minInputWork and minInputBreak. You seem not to understand what is being passed to this function when use it as listener argument (callback function) of the addEventListener .

The listener callback function only has one argument which is the Event object containing various properties about the event which occurred.

Your first argument of clock is minInputWork which will be passed the click Event object and not the value of the input element with id=“work” which is I think what you thought was being used. If you want to use that input value, then move the following line inside the clock

let minInputWork = document.querySelector('#work').value

Hopefully this will get you started and/or someone else will respond to give you more assistance to your questions.


#5

Since you have a cascade of issues, it’s best to troubleshoot one at a time. Sometimes fixing one can fix/break other areas.

So for issue #1.

And your code

let minInputWork = document.querySelector('#work').value
let minInputBreak = document.querySelector('#break').value
...

function clock (minInputWork, minInputBreak){
...

You are retrieving the value of the element as soon as the page loads, which is empty at that point. Therefore you do not have anything to pass into your function clock.

You can only call the clock function after you get the values entered. Which means the variables will be available only inside that function’s scope.

Solution:

Best practice is to set your variables inside the uppermost function who’s scope needs the variable.

function  clock () {
  let minInputWork = document.querySelector('#work').value
  let minInputBreak = document.querySelector('#break').value

...
}

Do that, then see if any other issues pop up. Then come back here and we’ll continue troubleshooting.


#6

Ok. It’s listening again. That took such an effort. I thought I had tried this form before. That’s why I’m so stuck, because I think I’ve tried everything and my brain is just addled :frowning:

So it’s doing a basic count now. But oddly it’s skipping a number which originally; before I started preparing it to work with HTML it wasn’t.

It’s not counting this right:

WorkTime Input: ${minInputWork},

Also it’s now not running the second function for the ‘Break’ (2nd function).

const startClock = document.querySelector('.startBtn')
const stopClock = document.querySelector('#countdown')

let clockTimeRemaining;
let breakTimeRemaining;
let killedPomo;

stopClock.addEventListener('click', killedPomo)
startClock.addEventListener('click', clock)


function clock (){
  const startDate = Date.now()
  let minInputWork = document.querySelector('#work').value
  let minInputBreak = document.querySelector('#break').value


  const endDate = function getEndDate (startDate, minInputWork){
    return startDate + minInputWork * 60 * 1000 }
  const breakEndDate = function getEndBreakDate(startDate, minInputWork, minInputBreak){
    return startDate + (minInputWork + minInputBreak) * 60 * 1000 }//Convert to millies


  console.log(`WorkTime Input: ${minInputWork}, BreakTime Input: ${minInputBreak}, EndDate: ${endDate(startDate, minInputWork)}, StartDate: ${startDate}`);

  startWorking()  // Call startWorking function
  function startWorking (){
    const timer =
      setTimeout(()=>{
        clockTimeRemaining = Math.floor((endDate(startDate, minInputWork) - Date.now())/1000/60)
        console.log('timer Counter', clockTimeRemaining)
        if(clockTimeRemaining <= 0){
          clearInterval(timer)
          console.log('End Timer')
          startBreak()
        }
      },1000)
  }
  function startBreak (){
    const breakTimer =
      setTimeout(()=>{
        breakTimeRemaining = Math.floor((breakEndDate(startDate, minInputWork, minInputBreak) - Date.now())/1000/60)
          console.log('break Counter', breakTimeRemaining)
          if(breakTimeRemaining < 0){
            clearInterval(breakTimer)
            console.log('End Break')
            clock(minInputWork, minInputBreak)
          }
      },1000)
  }
  killedPomo =
    function killClock (timer, breakTimer){
      return clearInterval(timer), clearInterval(breakTimer)
    }
}

#7

I fixed that problem. I am always struggling with something to do with element selectors in JS. No idea why I’m so dense about it. Feels like I’ve gotten worse since the Algos tbh. Thank you though. Revised version has been put up!


#8

You had the timer set to setTimeout. My answer assumes you meant setInterval

The math you’re using to track the clockRemainingTime var

clockTimeRemaining = Math.floor((endDate(startDate, minInputWork) - Date.now())/1000/60)

is not returning what you think it is. And since you’re flooring the result, you will keep flooring to the same number.

01


#9

I got it!! Thank you for your help. It sent me back to the drawing board with new ideas and some very helpful fixes.

Have an awesome week guys!