Front End Development Libraries Projects - Build a JavaScript Calculator

Tell us what’s happening:

I’m running into the issue of failing test #9, #12, #13, and #14 no matter what I do I can’t seem to pass them please help point me in the right direction I am working on VS Code if that makes a difference

Your code so far

JS:

import { useState } from 'react';
import './App.css';

function App() {
  const [answer, setAnswer] = useState("");
  const [expression, setExpression] = useState("0");
  const [lastAction, setLastAction] = useState(""); // Track the last action

  const isOperator = (symbol: string) => /[-+*/]/.test(symbol);

  const buttonPress = (symbol: string) => {
    console.log(`Button pressed: ${symbol}`);
    if (symbol === "clear") {
      setAnswer("");
      setExpression("0");
      setLastAction("");
      console.log("Cleared");
    } else if (symbol === "percent") {
      if (answer === "") return;
      setAnswer((parseFloat(answer) / 100).toString());
      console.log(`Percent: ${answer}`);
    } else if (isOperator(symbol)) {
      if (lastAction === "=") {
        setExpression(answer + " " + symbol + " ");
        console.log(`Operator after equals: ${expression}`);
      } else if (!isOperator(expression.charAt(expression.length - 1))) {
        setExpression(expression + " " + symbol + " ");
        console.log(`Operator: ${expression}`);
      } else {
        setExpression(expression.slice(0, -3) + " " + symbol + " ");
        console.log(`Replace operator: ${expression}`);
      }
      setLastAction(symbol);
    } else if (symbol === "=") {
      calculate();
      setLastAction("=");
    } else if (symbol === "0") {
      if (expression !== "0") {
        setExpression(expression + symbol);
        console.log(`Zero: ${expression}`);
      }
      setLastAction(symbol);
    } else if (symbol === ".") {
      const lastNumber = expression.split(/[-+*/]/g).pop();
      if (lastNumber?.includes(".")) return;
      setExpression(expression + symbol);
      console.log(`Decimal: ${expression}`);
      setLastAction(symbol);
    } else {
      setExpression(expression === "0" || lastAction === "=" ? symbol : expression + symbol);
      console.log(`Number: ${expression}`);
      setLastAction(symbol);
    }
  };

  const calculate = () => {
    try {
      const result = eval(expression.replace(/ /g, ""));
      const preciseResult = parseFloat(result.toFixed(4));
      setAnswer(preciseResult.toString());
      setExpression(preciseResult.toString()); // Update expression to the result
      console.log(`Calculated result: ${preciseResult}`);
    } catch (e) {
      setAnswer("Error");
      console.log("Calculation error");
    }
  };

  return (
    <div className="container">
      <div id='calculator'>
        <div id="display" style={{ textAlign: 'right' }}>
          <div id="expression">{expression}</div>
          <div id="answer">{answer}</div>
        </div>
        <button id="clear" onClick={() => buttonPress("clear")} className="light-gray">C</button>
        <button id="percentage" onClick={() => buttonPress("percent")} className="light-gray">%</button>
        <button id="divide" onClick={() => buttonPress("/")} className="yellow">/</button>
        <button id="seven" onClick={() => buttonPress("7")} className="dark-gray">7</button>
        <button id="eight" onClick={() => buttonPress("8")} className="dark-gray">8</button>
        <button id="nine" onClick={() => buttonPress("9")} className="dark-gray">9</button>
        <button id="multiply" onClick={() => buttonPress("*")} className="yellow">*</button>
        <button id="four" onClick={() => buttonPress("4")} className="dark-gray">4</button>
        <button id="five" onClick={() => buttonPress("5")} className="dark-gray">5</button>
        <button id="six" onClick={() => buttonPress("6")} className="dark-gray">6</button>
        <button id="subtract" onClick={() => buttonPress("-")} className="yellow">-</button>
        <button id="one" onClick={() => buttonPress("1")} className="dark-gray">1</button>
        <button id="two" onClick={() => buttonPress("2")} className="dark-gray">2</button>
        <button id="three" onClick={() => buttonPress("3")} className="dark-gray">3</button>
        <button id="add" onClick={() => buttonPress("+")} className="yellow">+</button>
        <button id="zero" onClick={() => buttonPress("0")} className="dark-gray">0</button>
        <button id="decimal" onClick={() => buttonPress(".")} className="dark-gray">.</button>
        <button id="equals" onClick={() => buttonPress("=")} className="yellow">=</button>
      </div>
    </div>
  );
}

export default App;

CSS:

:root {
  --white: white;
  --light-gray: #fefefe;
  --dark-gray: #6c6c6c;
  --black: #1e1e1e;
  --yellow: #f99c14;
}

.container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

#calculator {
  display: grid;
  grid-template-areas: 
    "display display display display"
    "clear clear percentage divide"
    "seven eight nine multiply"
    "four five six subtract"
    "one two three add"
    "zero zero decimal equals";
    grid-template-columns: 100px 100px 100px 100px;
    gap: 20px;
    padding: 50ox;
    padding-top: 10px;
    margin-top: 20px;
    border-radius: 20px;
    background-color: var(--black);
}

.light-gray {
  background-color: var(--light-gray);
}

.dark-gray {
  background-color: var(--dark-gray);
  color: var(--white);
}

.black {
  background-color: var(--black);
}

.yellow {
  background-color: var(--yellow);
  color: var(--white);
}

button {
  height: 100px;
  font-size: 24px;
  border: none;
  cursor: pointer;
  border-radius: 100px;
  width: 100%;
  transition: transform 0.1s ease-in-out;
}

button:active {
  transform: scale(0.95);
}

#answer {
  height: 48px;
  font-size: 48px;

}

#expression {
  font-size: 30px;
  height: 30px;
  color: var(--dark-gray);
}

#divide {
  grid-area: divide;
}

#clear {
  grid-area: clear;
}

#percentage {
  grid-area: percentage;
}
#seven {
  grid-area: seven;
}
#eight {
  grid-area: eight;
}
#nine {
  grid-area: nine;
}
#multiply {
  grid-area: multiply;
}
#four {
  grid-area: four;
}
#five {
  grid-area: five;
}
#six {
  grid-area: six;
}
#subtract {
  grid-area: subtract;
}
#one {
  grid-area: one;
}
#two {
  grid-area: two;
}
#three {
  grid-area: three;
}
#add {
  grid-area: add;
}
#zero {
  grid-area: zero;
}
#decimal {
  grid-area: decimal;
}
#equals {
  grid-area: equals;
}

#display {
  grid-area: display;
}

HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Calculator</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js"></script>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>

Your browser information:

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

Challenge Information:

Front End Development Libraries Projects - Build a JavaScript Calculator

do you have a codepen or something like that? it is easier to debug with a project with the tests

when i put my code into codepen i get a blank black screen

if you share the pen someone could help you to make it work

You are not outputting correctly to the display element. The test does not expect it to contain two other elements.

For example, this change to the JSX would make your code pass all but the last test (which is just not giving the correct answer).

<div style={{ textAlign: "right" }}>
  <div id="expression">{expression}</div>
  <div id="display">{expression || answer}</div>
</div>

thankyou for your help i greatly appreciate it i am now only failing test 13 but i think ive figured it out