Stuck with 25+5 timer (Front End Development Libraries project #5)

Hello! My Name is Gerardo. I’m stuck with the project n°5 25+5 timer. I try it at least 3 times from scratch, but even if i can get the project to function correctly (or at least, as long as i can tell) i can’t seem to pass the test.
The last time I tried it ([https://clever-brown-0d6c02.netlify.app/](here, hosted in Netlify)), I set myself to be as straight foward an simple as I (being a complete begginer) could: i use only React, with a single component, only using useState and useEffect hooks, with all in-line functions, so I can’t be messing it up with poor use of useReducer or Redux or anything… Still, the same result…
Below I copy the project’s silly code,

import { useRef, useState, useEffect } from 'react'
import reducer from './reducer'
import { IoIosArrowDown, IoIosArrowUp } from 'react-icons/io'
import { FaPlay, FaPause } from 'react-icons/fa'
import { VscDebugRestart } from 'react-icons/vsc'

function App() {
  const [breakLength, setBreakLength] = useState(5)
  const [sessionLength, setSessionLength] = useState(25)
  const [clock, setClock] = useState(sessionLength * 60)
  const [isClockRunning, setIsClockRunning] = useState(false)
  const [isSessionCycle, setIsSessionCycle] = useState(true)
  const [isCountdownFinished, setIsCountdownFinished] = useState(false)

  const audioRef = useRef(null)
  const formatTime = (time) => {
    const min = Math.floor(time / 60)
    const sec = Math.floor(time % 60)
    return {
      min: min < 10 ? `0${min}` : min,
      sec: sec < 10 ? `0${sec}` : sec,
    }
  }
  useEffect(() => {
    if (clock === 0) {
      setIsSessionCycle(!isSessionCycle)
      setClock(isSessionCycle ? breakLength * 60 : sessionLength * 60)
      setIsCountdownFinished(true)
      audioRef.current.play()
      const timeout = setTimeout(() => {
        setIsCountdownFinished(false)
      }, 2000)
    }
    if (isClockRunning && !isCountdownFinished) {
      const clockInt = setInterval(() => {
        setClock(clock - 1)
      }, 1000)
      return () => clearInterval(clockInt)
    }
  }, [isClockRunning, clock, isCountdownFinished])
  return (
    <section className='section-center'>
      <h1 className='title'>25+5 Clock</h1>
      <div className='clock-container'>
        <div className='break-session-container'>
          <article className='session-container'>
            <h4 className='container-title' id='session-label'>
              Session Lenght
            </h4>
            <div className='btn-container'>
              <IoIosArrowDown
                className='icon'
                id='session-decrement'
                onClick={() => {
                  if (!isClockRunning) {
                    sessionLength > 1 && setSessionLength(sessionLength - 1)
                    isSessionCycle &&
                      sessionLength > 1 &&
                      setClock((sessionLength - 1) * 60)
                  }
                }}
              />
              <p className='Session-time time' id='session-length'>
                {sessionLength}
              </p>
              <IoIosArrowUp
                className='icon'
                id='session-increment'
                onClick={() => {
                  if (!isClockRunning) {
                    sessionLength < 60 && setSessionLength(sessionLength + 1)
                    isSessionCycle &&
                      sessionLength < 60 &&
                      setClock((sessionLength + 1) * 60)
                  }
                }}
              />
            </div>
          </article>
          <article className='break-container'>
            <h4 className='container-title' id='break-label'>
              Break Length
            </h4>
            <div className='btn-container'>
              <IoIosArrowDown
                className='icon'
                id='break-decrement'
                onClick={() => {
                  if (!isClockRunning) {
                    breakLength > 1 && setBreakLength(breakLength - 1)
                    !isSessionCycle &&
                      breakLength > 1 &&
                      setClock((breakLength - 1) * 60)
                  }
                }}
              />

              <p className='break-time time' id='break-length'>
                {breakLength}
              </p>
              <IoIosArrowUp
                className='icon'
                id='break-increment'
                onClick={() => {
                  if (!isClockRunning) {
                    breakLength < 60 && setBreakLength(breakLength + 1)
                    !isSessionCycle &&
                      breakLength < 60 &&
                      setClock((breakLength + 1) * 60)
                  }
                }}
              />
            </div>
          </article>
        </div>
        <article className={`display ${isCountdownFinished ? 'danger' : ''}`}>
          <h4 className='display-title' id='timer-label'>
            {isSessionCycle ? 'Session' : 'Break'}
          </h4>
          <h2 className='display-time' id='time-left'>
            {formatTime(clock).min}:{formatTime(clock).sec}
          </h2>
          <audio
            src='https://sampleswap.org/samples-ghost/DRUMS%20(SINGLE%20HITS)/Gongs%20and%20Super%20Crashes/1364[kb]muted_gong.wav.mp3'
            ref={audioRef}
            id='beep'
          ></audio>
        </article>
        <div className='control-btns'>
          <button
            id='start_stop'
            onClick={() => {
              setIsClockRunning(!isClockRunning)
            }}
          >
            {isClockRunning ? (
              <FaPause className='icon' />
            ) : (
              <FaPlay className='icon' />
            )}
          </button>
          <VscDebugRestart
            className='icon'
            id='reset'
            onClick={() => {
              audioRef.current.pause()
              audioRef.current.currentTime = 0
              setBreakLength(5)
              setSessionLength(25)
              setClock(1500)
              setIsClockRunning(false)
              setIsSessionCycle(true)
              setIsCountdownFinished(false)
            }}
          />
        </div>
      </div>
    </section>
  )
}

export default App

I’m deeply sorry to crowd this forum with a topic like this, but i can’t seem to find my way to pass this. Can you spot and tell me where my error/s is/are?
Thanks so much!

I notice your timer never actually reaches and displays “00:00”, it stops at “00:01” and then resets. Your timer must reach zero and play the audio at that point to pass the test. I would fix that, then rerun the test.

1 Like

Thanks friend! The fact that i missed a detail like that make me realize that i could do much better! I think that now that it actually reach 00:00 it works better…
It still don’t pass the test, though…

oh i had great troubles working this project out as well and it didnt help it was the first time i dare use react hooks and get to learn them along the line. My greatest issue was working with the setInterval method, when its supposed to be cleared etc. At some point i even made all tests pass initially, but the timer woould misfire right after tests were undergone, making the app actually broken. In the end one clearInterval at the right spot made it finally click
https://codepen.io/Sylvant/pen/WNoodVo?editors=0110

This is it. It uses very similar techniques and technologies as yourse so maybe just checking my code can help you figure out where yours fail.
PS: the class constructor in the start is meant to produce the objects holding properties for some elements, dont dwell too much about it.

1 Like

Thank you very much for your Reply!
Looking at the way you tackle this was very insightful. You clearly had a much more elegant aproach that I did.
The funny thing is, after I looked at your code and learned a thing or two, I tried it myself again trying to imitate your functionallity… and ended up with the same result as before. I must say, i was really shocked :frowning_face:
After that, it take me an inmense amount of time, but I think I reached a conclussion:
The test-thing does not work with React-Icons :exploding_head:
So I tried again the same old project that I shared before, but WITHOUT the React-Icons components and voila! Now the project (the same that didn’t pass before) now pass the test!
Guess I will leave it like that (with a crappy no-icon look), for the last couple of days were really frustraiting and I don’t really have the stomach to keep looking that clock :sweat_smile:
Anyway, thanks for the help!!!

Im sorry you went thru such inconvenience, its unfortunate your project was failing for somethign so silly. Like i said i also spent a good amount of time frustrated over this project and only made it work more by chance than insight on the code. Nevertheless you shouldnt regret your time spent as im sure you’ve learned a lot(the clear setInterval method is gonna be a badge i carry on my sleeve :slight_smile: )

1 Like

Yeah man, you’re right!
Also, I really liked the design of your project and I think that I really can learn a lot trying to get the project to look nice…
Again, thanks for your kind words and support!

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.