Pomodoro Timer works fine, but not passing 7 tests

The tests I’m currently not passing are as follows:

  • time-left is not formatted correctly: expected '25' to equal '60' (if I change the default value to 60, it says it expected ‘60’ to equal ‘25’)
  • all six increment/decrement ones, including the 1 <= x <= 60 one, since it doesn’t seem to recognise a change in the display elements at all (even though, testing it out manually, it changes and works properly)
  • sometimes (not always) it doesn’t pass the audio test for playing at 00:00, saying the timer never reaches it, even though it does (and is the trigger condition for playing the audio, which is audible at that moment)

Been stumped at this for quite a bit now, especially since another post on the forums that ran into similar problems said theirs was solved by just finishing a working timer, but mine persist after having finished.

I tried moving the #break-length and #session-length ids to the div from the heading, but that didn’t change it.

Here is my JavaScript:

const AUDIO_URL = "https://media1.vocaroo.com/mp3/1gxUA2K74vln";
const DISPLAY_SESSION = "Current Session";
const DISPLAY_BREAK = "Current Break";
const DEFAULT_STATE = {sessionTime: 25, breakTime: 5, playing: false, break: false, displayTime: "25:00", currentDuration: 1500, reset: true};

let timer = null;

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = DEFAULT_STATE;
    this.togglePlaying = this.togglePlaying.bind(this);
    this.resetTimer = this.resetTimer.bind(this);
    this.changeSessionLength = this.changeSessionLength.bind(this);
    this.changeBreakLength = this.changeBreakLength.bind(this);
  }
  
  togglePlaying() {
    this.setState((state) =>({playing: !state.playing}), () => this.runTimer());
  }
  
  resetTimer() {
    this.setState(DEFAULT_STATE);
    clearInterval(timer);
    document.getElementById("beep").pause();
    document.getElementById("beep").currentTime = 0;
  }
  
  runTimer() {
    this.setState({reset: false});
    if (this.state.playing) {
      timer = setInterval(() => {
       let mins = Math.floor(this.state.currentDuration / 60);
       let secs = this.state.currentDuration % 60;
        console.log("mins: " + mins + ", secs: " + secs);
        let toggleBreak = false
        if (secs <= 0) {
          console.log("non-positive seconds: " + secs);
          if (mins > 0) {
            console.log("positive minutes: " + mins);
            secs = 59;
            mins--;
          } else {
            if (mins == 0 && secs == 0) document.getElementById("beep").play();
            console.log("non-positive minutes: " + mins);
            secs = 0;
            mins = (!this.state.break) ? this.state.breakTime : this.state.sessionTime;
            toggleBreak = true;
          }
        } else {
          secs--;
        }
        
        let newDur = mins*60 + secs;
        let durString = "";
        durString += ((mins < 10) ? "0" + mins : mins);
        durString += ":"
        durString += ((secs < 10) ? "0" + secs : secs);
        this.setState({currentDuration: newDur, displayTime: durString});
        
        if (toggleBreak) {
          this.setState((state) => ({currentMinutes: mins, currentSeconds: secs, break: !state.break}));
        } else {
          this.setState({currentMinutes: mins, currentSeconds: secs});
        }
      }, 1000);
    } else {
      clearInterval(timer);
    }
  }
  
  changeSessionLength(e) {
    if (e.target.className == "fas fa-angle-left") {
      if (this.state.sessionTime > 1) {
        this.setState((state) => ({sessionTime: state.sessionTime - 1}));
      }
    } else if (e.target.className == "fas fa-angle-right") {
      if (this.state.sessionTime < 60) {
        this.setState((state) => ({sessionTime: state.sessionTime + 1}));
      }
    }
    if (!this.state.playing && this.state.reset) {
          this.setState((state) => ({displayTime: state.sessionTime + ":00", currentDuration: 60*state.sessionTime}));
        }
  }
  
  changeBreakLength(e) {
    if (e.target.className == "fas fa-angle-left") {
      if (this.state.breakTime > 1) {
        this.setState((state) => ({breakTime: state.breakTime - 1}));
      }
    } else if (e.target.className == "fas fa-angle-right") {
      if (this.state.breakTime < 180) {
        this.setState((state) => ({breakTime: state.breakTime + 1}));
      }
    }
  }
  
  render() {
    return (
      <div class="container">
        <div class="row">
          <div class="col">
            <h1>Pomodoro Timer</h1>
          </div>
        </div>
        <br />
        <Settings sessionValue={this.state.sessionTime} breakValue={this.state.breakTime} sessionCallback={this.changeSessionLength} breakCallback={this.changeBreakLength}  />
        <br />
        <Session displayValue={this.state.displayTime} playing={this.state.playing} togglePlaying={this.togglePlaying} resetCallback={this.resetTimer} displayText={(this.state.break) ? DISPLAY_BREAK : DISPLAY_SESSION}/>
      </div>
    );
  }
}

class Settings extends React.Component {
  render() {
    return (
      <div class="row">
        <div class="col-6">
          <div class="row">
            <div class="col">
              <h2 id="session-label">Session Length</h2>
            </div>
          </div>
          <div class="row">
            <div class="col text-right" id="session-decrement" onClick={this.props.sessionCallback}>
              <i class="fas fa-angle-left"></i>
            </div>
            <div class="col-4 text-center">
                <h2 id="session-length">{this.props.sessionValue}</h2>
            </div>
            <div class="col text-left" id="session-increment" onClick={this.props.sessionCallback}>
              <i class="fas fa-angle-right"></i>
            </div>
          </div>
        </div>
        <div class="col-6">
          <div class="row">
            <div class="col">
              <h2 id="break-label">Break Length</h2>
            </div>
          </div>
          <div class="row">
            <div class="col text-right" id="break-decrement" onClick={this.props.breakCallback}>
              <i class="fas fa-angle-left"></i>
            </div>
            <div class="col-4 text-center">
                <h2 id="break-length">{this.props.breakValue}</h2>
            </div>
            <div class="col text-left" id="break-increment" onClick={this.props.breakCallback}>
              <i class="fas fa-angle-right"></i>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

class Session extends React.Component {
  render() {
    return (
      <div class="row">
        <div class="col" />
        <div class="col-6" id="session">
          <div class="row">
            <div class="col">
              <h3 id="timer-label">{this.props.displayText}</h3>
            </div>
          </div>
          <div class="row">
            <div class="col">
              <h1 id="time-left">{this.props.displayValue}</h1>
            </div>
          </div>
          <div class="row">
            <div class="col-6 text-right">
              <div id="start_stop" class="ctrl-btn-container" onClick={this.props.togglePlaying}>
                <i class={"fas " + ((this.props.playing) ? "fa-pause" : "fa-play")}></i>
              </div>
             </div>
            <div class="col-6 text-left">
              <div id="reset" class="ctrl-btn-container" onClick={this.props.resetCallback}>
                <i class = "fas fa-trash ctrl-icons" id="reset"></i>
            </div>
            </div>
          </div>
        </div>
        <div class="col" />
        <audio src={AUDIO_URL} id="beep"></audio>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("app"));

Can you post a link to your app on codepen? It might help find the error easier.

Sorry, probably should’ve done that in the first place: there you go

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