In this React Pomodoro clock, setInterval calls down every time state.timeLeftSeconds is reduced. However, when attempting to pass the freecodecamp tests 12 and 13, there is a message: Break time didn't start with the correct value.: expected 60 to be at most 5. Yet, when the clock is run the code appears to be working perfectly. Any help would be greatly appreciated. The testing suite is also there in the code sandbox: https://codesandbox.io/s/xenodochial-fog-981wl
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './style.css';
/*
* A simple React component
*/
const initState = {
breakLength: 5,
sessionLength: 25,
init: 'session',
stateIndex: 0,
timeLeft: undefined,
timeLeftSeconds: undefined,
started: false,
intervalFunc: undefined
}
const states = [ { name: 'session', duration: 1500 }, { name: 'break', duration: 300 } ]
const secondsToMins = (time) => {
let converted = ('0' + Math.floor(time / 60)).slice(-2) + ':' + ('0' + Math.floor(time % 60)).slice(-2);
return converted;
}
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = initState;
this.breakDecrement = this.breakDecrement.bind(this);
this.breakIncrement = this.breakIncrement.bind(this);
this.sessionDecrement = this.sessionDecrement.bind(this);
this.sessionIncrement = this.sessionIncrement.bind(this);
this.startStop = this.startStop.bind(this);
this.reset = this.reset.bind(this);
}
componentDidMount() {
let sessionSeconds = this.state.sessionLength * 60;
this.setState({ timeLeftSeconds: sessionSeconds });
this.setState({ timeLeft: secondsToMins(sessionSeconds) });
}
breakDecrement() {
// decrements the breakLength and the breakSeconds
// breakLength is only a number ie. 5 (does not show seconds)
// breakSeconds is that nunber converted into seconds
let breakLength = this.state.breakLength - 1;
if (breakLength > 0 && breakLength < 61){
this.setState({ breakLength: breakLength });
let breakSeconds = breakLength * 60;
states[1]['duration'] = breakSeconds;
}
}
breakIncrement() {
// same as decrement except does increment
let breakLength = this.state.breakLength + 1;
if (breakLength > 0 && breakLength < 61){
this.setState({ breakLength: breakLength });
let breakSeconds = breakLength * 60;
states[1]['duration'] = breakSeconds;
}
}
sessionDecrement() {
// decrements the sessionLength and the sessionSeconds
// sessionLength is only a number ie. 25 (does not show seconds)
// sessionSeconds is that nunber converted into seconds
let sessionLength = this.state.sessionLength - 1;
if (sessionLength > 0 && sessionLength < 61){
states[0]['duration'] = sessionLength*60;
this.setState(prevState => ({
sessionLength: prevState.sessionLength-1,
timeLeftSeconds: (prevState.sessionLength-1)*60,
timeLeft: secondsToMins((prevState.sessionLength-1)*60)})
);
}
}
sessionIncrement() {
// same as decrement except does increment
let sessionLength = this.state.sessionLength + 1;
if (sessionLength > 0 && sessionLength < 61){
states[0]['duration'] = sessionLength*60;
this.setState(prevState => ({
sessionLength: prevState.sessionLength+1,
timeLeftSeconds: (prevState.sessionLength+1)*60,
timeLeft: secondsToMins((prevState.sessionLength+1)*60)})
);
}
}
startStop(id) {
// starts the countDown, which runs continuously until the start/stop button
// is pressed again, which pauses the countdown.
// the id parameter is used by countDown to play the audio beep
if(!this.state.started){
this.countDown(id);
this.setState({ started: true});
}
// pauses the countDown
if(this.state.started){
let intervalFunc = this.state.intervalFunc;
clearInterval(intervalFunc);
this.setState({ started: false});
}
}
reset() {
let intervalFunc = this.state.intervalFunc;
clearInterval(intervalFunc);
// reset state to default values
this.setState({ breakLength: 5 });
this.setState({ sessionLength: 25 });
this.setState({ init: 'session' });
this.setState({ timeLeftSeconds: 1500})
this.setState({ timeLeft: '25:00' });
this.setState({ stateIndex: 0 });
this.setState({ started: false });
this.setState({ intervalFunc: undefined });
}
decreaseCurrentSecond = () => this.state.timeLeftSeconds--;
countDown(id) {
// set the function to a variable and set state to it, so the function
// can be paused with clearInterval()
var intervalFunc = setInterval(
() => down(this.decreaseCurrentSecond()),
1000
);
this.setState({ intervalFunc: intervalFunc });
const down = (time) => {
if (time > 0) {
// converts seconds to MM:SS at every t-minus
this.setState({ timeLeft: secondsToMins(time) });
/*
console.log(time);
console.log(this.state.timeLeft);*/
}
let sound = document.getElementById(id).childNodes[0];
if (time <= 0 ) {
sound.play();
this.setState({ timeLeft: secondsToMins(time) });
console.log(time);
console.log(this.stateIndex);
console.log(this.state.init);
console.log(this.state.timeLeftSeconds);
let stateIndex = (this.state.stateIndex + 1) % states.length;
this.setState({ stateIndex: stateIndex });
this.setState({ init: states[stateIndex]['name'] });
this.setState({ timeLeftSeconds: states[stateIndex]['duration'] });
console.log(time);
console.log(this.stateIndex);
console.log(this.state.init);
console.log(this.state.timeLeftSeconds);
}
};
down(this.decreaseCurrentSecond());
}
render() {
return (
<div id="clock">
<h1 id="title">25-5 Clock</h1>
<div>
<p id="break-label">Break Length</p>
<p id="break-length">{this.state.breakLength}</p>
<button id="break-decrement" onClick={e => this.breakDecrement()}> Decrease </button>
<button id="break-increment" onClick={e => this.breakIncrement()}> Increase </button>
</div>
<div>
<p id="session-label">Session Length</p>
<p id="session-length">{this.state.sessionLength}</p>
<button id="session-decrement" onClick={e => this.sessionDecrement()}> Decrease </button>
<button id="session-increment" onClick={e => this.sessionIncrement()}> Increase </button>
</div>
<hr/>
<div>
<p id="timer-label">{this.state.init}</p>
<p id="time-left">{this.state.timeLeft}</p>
<button id="start_stop" onClick={e => this.startStop(e.target.id)}><audio id="beep" src='./beep.mp3'></audio> start/stop </button>
<button id="reset" onClick={e => this.reset()}> reset </button>
</div>
</div>
);
}
};
/*
* Render the above component into the div#app
*/
ReactDOM.render(<Clock />, document.getElementById("app"));
index.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>25-5 Clock</title>
<style>
</style>
</head>
<body>
<main>
<div id="app"></app>
</main>
</body>
</html>