25+5 Clock: "Can't read properties of null" & "Timer hasn't reached 0"

Can anyone enlighten me what the test spec is expecting? I think I’ve fulfilled all the user stories, function-wise, yet I still can’t pass the specs. There are 11 specs to pass, but all summed up to these 2 problems:

  1. Cannot read properties of null; and
  2. Timer has not reached 00:00

For #1 I thought it’s expecting an input element with .value, but when I checked the example with dev console, it uses regular div just like mine. Thus I wonder what did I miss.
For #2, I console.log(this.state.duration === 0), and it always printed true when the alarm beeped. Thus this question.

Thank you!

Your code so far

https://codepen.io/shugyoza/pen/yLoQpea?editors=1111

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36

Challenge: Build a 25 + 5 Clock

Link to the challenge:

First thing I noticed is your use of setTimeout and setInterval, which open up a whole can of bugs when used with React.

The argument passed to those functions is static. They have no way to fetch anything outside of the original state that you’ve passed to them, and you can see this by starting the timer, letting it run for a few seconds, pausing it, and then resuming it again. The timer actually jumps back up because setInterval doesn’t know what the current state is. It only knows the state that it was originally passed.

You’re using class based react, but this post sums things up much better than I can.

Thank you! your feedback is a game changer. Yes, setTimeout should not be used as it’s not tracked by this.state. Just by replacing the setTimeout with an if statement within the setInterval to invoke switch whenever (remaining) duration is -1000 (0 is suppose to be working, but the spec needs to see the 00:00 for a second, thus the -1000), it passed most specs, leaving 2 errors:

25 + 5 clock has paused but time continued elapsing: expected '53' to equal '55'

which means there’s a 2 seconds difference between the pause and replay during the test case running. Easy patch were to just add 2000ms and update the duration, which could make the app pass the test specs… on first run only, but if we ran a consecutive test, it’ll fail the subsequent test. Partly because at the end of the test, my clock kept running and could not be stopped nor reset.
This is the codes for the flawed app:

https://codepen.io/shugyoza/pen/wvqRPqx

After I tweaked some more, I passed all the specs with this one:

https://codepen.io/shugyoza/pen/RwZvNyE?editors=1111

Hypothetically, the two last mentioned errors were caused by my chaining the beep.play, this.setState(()=>), and clearInterval() SERIALLY, causing the different timestamps between the alarm sound started to play, the (left)state.duration captured, and the clearing of setInterval (as much as 2 seconds). This flaw was resolved by moving all of them inside the this.setState(()=>) callback function so that the state updating and the invocation of all required functions were done at once, thus they’re synchronized.

Also I moved the clearInterval() to on top of the reset() method so that either there is or there is not an active clock ticking, this clock will stop. Thus this fixed the symptom where after running the test specs, my clock were always kept ticking and can’t be stopped nor reset.

Thank you for your help! I hope this note may be beneficial for someone after me.