Front End Development Libraries Projects - Build a JavaScript Calculator

Tell us what’s happening:

I’ve got it almost 100% functional, the only issue now is I can’t seem to get the calculator to use the last operator and not the first.

This is the error i keep getting for User Story #13: The sequence “5 * - + 5” = should produce an output of “10” : expected ‘25’ to equal ‘10’

When inputting that string it is properly getting rid of the negative sign but is using the first operator to get the value of 25. Any help is always greatly appreciated. Thank you all so much and Happy Coding!

Your code so far

import './App.css'; import React from 'react';

const isOperator = /[x/±]/
const endsWithOperator = /[x±/]$/
const endsWithNegativeSign = /\d[x/±]{1}-$/

class Calculator extends React.Component {
constructor(props){
super(props);

  this.state = {
    currentValue: "0",
    previousValue: "0",
    formula: "",
    currentSign: "positive",
    lastClicked: ""
  };

  this.numbers = this.numbers.bind(this);
  this.operators = this.operators.bind(this);
  this.decimal = this.decimal.bind(this);
  this.clearAll = this.clearAll.bind(this);
  this.evaluateExpression = this.evaluateExpression.bind(this);

}

numbers(num) {
  const currentValue = this.state.currentValue === "0" ? num.toString() : this.state.currentValue + num;
  this.setState({
      currentValue,
      lastClicked: num
  });

}

operators(operator) {
const { currentValue, formula, lastClicked } = this.state;

if (operator === '-' && isOperator.test(lastClicked)) {
  this.setState({
    formula: formula + operator,
    currentValue: operator,
    lastClicked: operator
  });
} else if (isOperator.test(lastClicked) && isOperator.test(operator)) {
  const updatedFormula = formula.slice(0, -1) + operator;
  this.setState({
    formula: updatedFormula,
    lastClicked: operator
  });
} else {
  this.setState({
    formula: formula + currentValue + operator,
    currentValue: "",
    lastClicked: operator
  });
}

}

  decimal() {
      if (!this.state.currentValue.includes(".")) {
          this.setState({
              currentValue: this.state.currentValue + "."
          });
      }
  }


  clearAll() {
      this.setState({
          currentValue: "0",
          previousValue: "0",
          formula: "",
          currentSign: "positive",
          lastClicked: ""
      });
  }


  evaluateExpression() {
    let result;
    try {
      result = Math.round(1e12 * eval(this.state.formula + this.state.currentValue)) / 1e12;
      this.setState({
        currentValue: result.toString(),
        formula: "",
        previousValue: result.toString(),
        lastClicked: "="
      });
    } catch (error) {
      console.error("Invalid expression:", error);
      this.setState({
        currentValue: "Error",
        previousValue: "Error",
        formula: "",
        lastClicked: ""
      });
    }
  }

render() {

return (
  <div id="calculator">
    <div id="display">
        <p id="formula"> {this.state.formula} </p>
        <p id="output"> {this.state.currentValue} </p>
    </div>
    <div id="button-container">
        <button id="clear" onClick={this.clearAll}>AC</button>
        <button id="divide" onClick={() => this.operators("/")}>/</button>
    </div>
    <div id="button-container">
        <button id="seven" onClick={() => this.numbers("7")}>7</button>
        <button id="eight" onClick={() => this.numbers("8")}>8</button>
        <button id="nine" onClick={() => this.numbers("9")}>9</button>
        <button id="multiply" onClick={() => this.operators("*")}>*</button>
    </div>
    <div id="button-container">
        <button id="four" onClick={() => this.numbers("4")}>4</button>
        <button id="five" onClick={() => this.numbers("5")}>5</button>
        <button id="six" onClick={() => this.numbers("6")}>6</button>
        <button id="subtract" onClick={() => this.operators("-")}>-</button>
    </div>
    <div id="button-container">
        <button id="one" onClick={() => this.numbers("1")}>1</button>
        <button id="two" onClick={() => this.numbers("2")}>2</button>
        <button id="three" onClick={() => this.numbers("3")}>3</button>
        <button id="add" onClick={() => this.operators("+")}>+</button>
    </div>
    <div id="button-container">
        <button id="zero" onClick={() => this.numbers("0")}>0</button>
        <button id="decimal" onClick={this.decimal}>.</button>
        <button id="equals" onClick={this.evaluateExpression}>=</button>
    </div>
     
   </div>
);

}
}

function App() {
return(

); }

export default App;

Your browser information:

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

Challenge Information:

Front End Development Libraries Projects - Build a JavaScript Calculator

share your “codepen or repl or others like it” link including all these codes, that way it gets way better to troubleshoot, happy coding :slight_smile:

hope this helps, your code is a lot neater than mine when I did this project!

I had some problems with your regular expressions. Instead of x you should be checking for * since this is the character contributed by your multiplication button. Also that character ± doesn’t check for the right character codes I think you should use ’ + ’ and ’ - ’ but you will need to escape ’ - ’ since it will check for a range. /[x/+\-]/

for the operator logic if we take for instance 5 * - + 5 once the ’ + ’ is pressed you remove only one of the operators from the end of the formula leaving ’ * '. You need to remove all operators from the end when a non subtraction operator is pressed and also you need to remove all operators from the end if subtraction is the last operator and the current operator. I wouldn’t make the operator part of your currentValue at any point.

if (operator === '-' 
    && isOperator.test(lastClicked)
    && lastClicked != '-') {
/*
* formula: formula + operator
* lastClicked: operator
* currentValue: ""
*/
} else {
/*
* logic to remove all operators from end of formula
*
* formula: currentValue + updatedFormula + operator
* lastClicked: operator
* currentValue: ""
*/
}

Best of luck! :slight_smile:

realized a flaw in my logic here, if I try to compose something like 4 + 3 / 2
the ’ + ’ gets removed and I’m left with 43 / 2

to fix this I removed currentValue from the setState in the else block and instead included it in my declaration of updatedFormula to insulate the desired operator from the logic that mutates updatedFormula.

let updatedFormula = formula + currentValue