Build a One-Time Password Generator - Build a One-Time Password Generator

Tell us what’s happening:

After pressing “Check your code” it gets stuck in “running tests” and wont let me finish, I cannot fulfill the task.

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>OTP Generator</title>
    <link rel="stylesheet" href="styles.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.development.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.development.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.26.5/babel.min.js"></script>
    <script
      data-plugins="transform-modules-umd"
      type="text/babel"
      src="index.jsx"
    ></script>
</head>

<body>
    <div id="root"></div>
    <script
      data-plugins="transform-modules-umd"
      type="text/babel"
      data-presets="react"
      data-type="module"
    >
      import { OTPGenerator } from './index.jsx';
      ReactDOM.createRoot(document.getElementById('root')).render(<OTPGenerator />);
    </script>
</body>

</html>
/* file: styles.css */

/* file: index.jsx */
const { useState, useEffect, useRef } = React;

export const OTPGenerator = () => {

const [otp, setOtp] = useState('');
const [timer, setTimer] = useState(0);

const intervalRef = useRef(null);

const handleGenerator = () => {
const code = Math.floor(Math.random()*1000000)
  .toString()
  .padStart(6, "0");

  setOtp(code);

  setTimer(5);

  clearInterval(intervalRef.current);

   intervalRef.current = setInterval(() => {
     setTimer((prev) => {
       if (prev <= 1) {
         clearInterval(intervalRef.current);
         return 0
       }
       return prev -1
     })
   }, 1000 )
}

useEffect(() => {
 if (timer === 0) return;

 intervalRef.current = setInterval(() => {
   setTimer(prev => prev - 1)
 }, 1000);

 return () => {
   clearInterval(intervalRef.current);
 }
}, [timer]);

const display = () => {
  if (!otp) return "";
  if (timer > 0) {
    return `Expires in: ${timer} seconds`
  }
  return "OTP expired. Click the button to generate a new OTP."
}

  return (
    <div className="container">
    <h1 id="otp-title">OTP Generator</h1>
    <h2 id="otp-display">{ otp ? otp :"Click 'Generate OTP' to get a code"}</h2>
    <p id="otp-timer" aria-live="assertive">
    {
      display()
    }
    </p>
    <button id="generate-otp-button"
    onClick={handleGenerator}
    disabled={timer > 0}
    >Generate OTP</button>
    </div>
  )
};

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36

Challenge Information:

Build a One-Time Password Generator - Build a One-Time Password Generator

Hi @gers.e02 and welcome to the community!

The reason you are seeing that it is stuck at “running tests” is that you have infinite loop logic within your code. You are setting up duplicated timing intervals that create an infinite loop because you have the logic to handle timing inside handleGenerator and inside of your useEffect function.

The most effective solution I can think of is to strip the interval logic from handleGenerator and keep the timing inside of useEffect. You have it setup correctly; it’s just duplicated!

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