How to play sound exactly at 00:00? - Pomodoro Clock

So, when timer goes to 00:00 the state of the display changes and the sound plays at that moment. How can I make the sound play at exactly 00:00 and then change the display? Thanks in advance! Here’s my Pen and the relevant code:

let timerID = null;
function toggleClock() {
  if (!this.props.parentState.isPaused === false) {
    clearInterval(timerID);
    timerID = setInterval(() => this.getTime(), 1000);
  } else {
    clearInterval(timerID);
  }
}

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.getTime = this.getTime.bind(this);
    this.playBeep = this.playBeep.bind(this);
    resetClock = resetClock.bind(this);
    resetSound = resetSound.bind(this);
    toggleClock = toggleClock.bind(this);
    this.state = {
      minutes: this.props.minutes,
      seconds: "00"
    };
  }

  playBeep() {
    this.refs.beepSound.play();
  }

  getTime() {
    if (!this.props.isPaused) {
      if (this.state.minutes === "00" && this.state.seconds === "00") {
        this.playBeep();
        switch (this.props.parentState.type) {
          case "Session":
            let newBreakLen =
              this.props.parentState.breakLength >= 10
                ? this.props.parentState.breakLength
                : "0" + this.props.parentState.breakLength;
            this.setState({
              minutes: newBreakLen,
              seconds: "00"
            });
            this.props.handler({
              type: "Break",
              len: newBreakLen,
              sessionLength: this.props.parentState.sessionLength,
              breakLength: this.props.parentState.breakLength,
              isPaused: false
            });
            break;
          case "Break":
            let newSessionLen =
              this.props.parentState.sessionLength >= 10
                ? this.props.parentState.sessionLength
                : "0" + this.props.parentState.sessionLength;
            this.setState({
              minutes: newSessionLen,
              seconds: "00"
            });
            this.props.handler({
              type: "Session",
              len: newSessionLen,
              sessionLength: this.props.parentState.sessionLength,
              breakLength: this.props.parentState.breakLength,
              isPaused: false
            });
            break;
        }
      } else if (this.state.seconds === "00") {
        let newMin = Number(this.state.minutes) - 1;
        newMin = newMin >= 10 ? newMin.toString() : "0" + newMin.toString();
        this.setState({
          minutes: newMin,
          seconds: "59"
        });
      } else {
        let newSec = Number(this.state.seconds) - 1;
        newSec = newSec >= 10 ? newSec.toString() : "0" + newSec.toString();
        this.setState({
          minutes: this.state.minutes,
          seconds: newSec
        });
      }
    }
  }

  render() {
    return (
      <div>
        <h1 id={this.props.id}>
          {this.state.minutes}:{this.state.seconds}
        </h1>
        <audio
          id="beep"
          ref="beepSound"
          src="https://onlineclock.net/audio/options/default.mp3"
        >
          <source
            src="https://onlineclock.net/audio/options/default.mp3"
            type="audio/mpeg"
          />
        </audio>
      </div>
    );
  }
}

Oops!I forgot to put the time function in. I edited the question with the relevant code.

just remove it and add a handler for pause for example
Sorry late by me and no time to study in depth. I just point you towards the solution. I removed this line than it’s OK.

This condition checks if the timer is paused. So if it’s false it goes inside the if-statement. My issue is with timing. I’m not sure how your solution helps me…

I’m out from work, I’m going home + shower and if nobody helped in the interval, I promise you to give it a serious look after :wink:

I’ve identified where the problem is: When the getTime() function sets the time to 00:00 and then waits another 1000ms before changing the state and playing the sound but I don’t know how to fix this…

Sounds like you should be checking for the “00:00:00” when the timer has just changed. Right now you are checking for the condition before the timer has changed to the next time (at the beginning of your getTime function.

if (this.state.minutes === "00" && this.state.seconds === "00") {

I don’t know where to move it though because if I move it to the bottom in the next function call it will go inside this:

else if (this.state.seconds === "00") {
        let newMin = Number(this.state.minutes) - 1;
        newMin = newMin >= 10 ? newMin.toString() : "0" + newMin.toString();
        this.setState({
          minutes: newMin,
          seconds: "59"
        });

which will lead to negative time displayed…

I think I got it now. So now (I think) my Pen behaves exactly like the example and the only thing left is to figure out the timeout bug…

This doesn’t work when switching back to the session though. But thanks for the help anyways!

Thanks a lot for your time and patience. I’ll try to solve the timeout problem to pass the tests and then I guess I’ll do some refactoring with the help of the suggestions you provided.