AnthoVdo
AnthoVdo

Reputation: 224

react 25+5 clock for freecodecamp test fail

I’m making the 25 + 5 clock for the freecodecamp certification but 2 test failled.

The test 10 and 11 for the #Timer are wrong. " 25 + 5 clock has paused but time continued elapsing: expected ‘58’ to equal ‘59’ "

On my side, it’s working and you can test it yourself link to the deployed project here 1.

You can click the play and pause button as fast as you can, it work.

But the test not.

It’s for 2 days that I’m checking on stackoverflow, freecodecamp forum, google about this issue.

I did a lot of change but not possible to find the issue.

body component

import React from 'react';
import Compteur from './Compteur';
import Config from './Config';
import { useState, useEffect } from 'react';

const Body = () => {

const [sessionCounter, setSessionCounter] = useState(1500);
const [breakCounter, setBreakCounter] = useState(300);
const [counterScreenSession, setCounterScreenSession] = useState(sessionCounter);
const [play, setPlay] = useState(false);
const [session, setSession] = useState(true);

const handleSessionCounter = (e) => {
    let number = e.currentTarget.dataset.session
    if(number === "up"){
        if(sessionCounter<3600){
            return setSessionCounter(sessionCounter+60);
        }else{
            return sessionCounter;
        }
        
    }
    else{
        if(sessionCounter >= 120){
            return setSessionCounter(sessionCounter-60);
        }else{
            return sessionCounter;
        }
        
    }
}

const handleBreakCounter = (e) => {
    let number = e.currentTarget.dataset.breaker
    if(number === "up"){
        if(breakCounter<3600){
            return setBreakCounter(breakCounter+60);
        }else{
            return breakCounter;
        }
        
    }
    else{
        if(breakCounter >= 120){
            return setBreakCounter(breakCounter-60);
        }else{
            return breakCounter;
        }
        
    }
}

const handleClear = () => {
    setPlay(false);
    setSession(true);
    setBreakCounter(300);
    setSessionCounter(1500)
    document.getElementById("beep").pause();
    document.getElementById("beep").currentTime=0;
    return setCounterScreenSession(1500);
}

const handleCounterScreen = () => {
    setPlay(play=>!play);
}

useEffect(() => {

    if(play && counterScreenSession>0){
        const timer = window.setInterval(()=>{
            setCounterScreenSession(counterScreenSession => counterScreenSession-1);
     }, 1000);
     return ()=>{
            clearInterval(timer)
        }
    }

}, [play, counterScreenSession])


useEffect(() => {

    if(counterScreenSession===0 && session){
            document.getElementById("beep").play();
            setCounterScreenSession(breakCounter);
            setSession(!session);
    }

    if(counterScreenSession===0 && !session){
            setCounterScreenSession(sessionCounter);
            setSession(!session);
    }


}, [counterScreenSession, session, breakCounter, sessionCounter])

useEffect(()=>{

    return setCounterScreenSession(sessionCounter);

}, [sessionCounter, breakCounter])

const timeCounter = () =>{
    let minutes = Math.floor(counterScreenSession/60);
    let seconds = counterScreenSession%60;

    if(minutes<10){
        minutes = "0"+minutes;
    }

    if(seconds<10){
        seconds = "0"+seconds;
    }

    return `${minutes}:${seconds}`;
}


return (
    <div className="body">
    <Config handleBreakCounter={handleBreakCounter} handleSessionCounter={handleSessionCounter} 
sessionCounter={sessionCounter} breakCounter={breakCounter}/>
    <Compteur counterScreenSession={counterScreenSession} play={play} handleCounterScreen= 
{handleCounterScreen} handleClear={handleClear} session={session} sessionCounter={sessionCounter} 
timeCounter={timeCounter} breakCounter={breakCounter}/>
    </div>
);
};

export default Body;

Compteur component

    import React from 'react';
    import { AiFillPauseCircle, AiFillPlayCircle } from "react-icons/ai";
    import {VscDebugRestart} from "react-icons/vsc";
    import { CircularProgressbar } from 'react-circular-progressbar';
    import 'react-circular-progressbar/dist/styles.css';

    const Compteur = ({counterScreenSession, play, handleCounterScreen, handleClear, session, 
    timeCounter,breakCounter,sessionCounter}) => {

    
    return (
        <div className={"compteur"} >
            <div className="compteur__name" id="timer-label">{session? "Session" : "Break"}</div>
            <CircularProgressbar 
            className="compteur__animation" 
            value={counterScreenSession} 
            minValue={0} 
            maxValue={session? sessionCounter:breakCounter } 
            counterClockwise="true"
               styles={{
                path:{
                    stroke: "#005479"
                },
                trail:{
                    stroke:"#A8223A"
                }}
            } 
            />
            
            <div className="compteur__time"  
            className={counterScreenSession<600 && counterScreenSession%60<5?"compteur__time 
    compteur__name--red" : "compteur__time" }id="time-left">
            {
                /*
                counterScreenSession<600 && counterScreenSession%60<10 ?
                "0"+Math.floor(counterScreenSession/60)+":0"+counterScreenSession%60:
                counterScreenSession>599 && counterScreenSession%60<10 ?
                Math.floor(counterScreenSession/60)+":0"+counterScreenSession%60:
                counterScreenSession<600 && counterScreenSession%60>10 ?
                "0"+Math.floor(counterScreenSession/60)+":"+counterScreenSession%60:
                Math.floor(counterScreenSession/60)+":"+counterScreenSession%60  
                */
                timeCounter()
            }
            </div>
            <audio id="beep" src="./sound/duke-game-over.mp3"></audio>
            <div className="compteur__controler">
            {
                play === false ?<button className="compteur__controler__play" id="start_stop" onClick= 
    {handleCounterScreen} ><AiFillPlayCircle/></button>:<button className="compteur__controler__break" 
    onClick={handleCounterScreen}><AiFillPauseCircle/></button>
            }
                
                
                <button className="compteur__controler__clear" id="reset" onClick={handleClear}> 
   <VscDebugRestart/></button>
            </div>
        </div>
     );
     };

    export default Compteur;

Link to the repo on github here.

Upvotes: 0

Views: 565

Answers (1)

imstoopid
imstoopid

Reputation: 7

I had the same problem and solved it using a class-based solution.

What I had was 53 - 55. It means there's a 2000ms (in your case is 1000ms) difference between the time the test case was paused and the time the test case replayed. The problem was because I chained the beep sound play, then setting the state (switching session-break), and clearing the interval (so it was serially firing three different functions). It was solved when I moved the beep sound play and switching session-break, all together within the function that invokes clearInterval (so they're all "fired together" in that function).

That chaining might've happened here:

if(counterScreenSession===0 && session){
        document.getElementById("beep").play();
        setCounterScreenSession(breakCounter);
        setSession(!session);
}

if(counterScreenSession===0 && !session){
        setCounterScreenSession(sessionCounter);
        setSession(!session);
}

So if I were you, I probably would try to incorporate those beep play and setsession within the return function in the else statement here, together with the clearInterval. Not sure if it'll work out though, I'm not even sure it could be played that way, but it might be worth it to toy around with that idea.

if(play && counterScreenSession>0){
    const timer = window.setInterval(()=>{
        setCounterScreenSession(counterScreenSession => counterScreenSession-1);
 }, 1000);
 return ()=>{
        clearInterval(timer)
    }
}

Upvotes: 1

Related Questions