JavaScript Calculator having trouble with '-' operator

Tell us what’s happening:
Describe your issue in detail here.

Hello, I’m facing difficulties in passing the last user story I need:

  1. If 2 or more operators are entered consecutively, the operation performed should be the last operator entered (excluding the negative (-) sign.

My current code is:
else if ((
this.state.lastPress == '+' ||
this.state.lastPress == '-' ||
this.state.lastPress == '/' ||
this.state.lastPress == '*')) {
let arr = this.state.prevNum.split("")
let arr2 = arr.slice(0,arr.length-1)
let str = arr2.join("") + op
this.setState({
lastPress: op,
currNum: undefined,
prevNum: str
})
}
to change the last operator when another operator button is pressed.

I tried using
else if (op == '-') {
this.setState({
lastPress: op,
prevNum: this.state.prevNum + innerOp,
currNum: undefined
})
}
to make '-' an exception, but not only it didn’t pass the user story, '-'
operator became the buggy button with the ability to assign indefinite numbers of operators together, causing the calculator to lose its function, unable to calculate anything.

Any suggestions on how I can fix this? Has anyone else encountered the same problem in the past, asked the forums, and got a solution thread elsewhere? If there is, I’d thank you deeply if you can post the link to said solution. Any kind of response will be greatly appreciated, thank you.

Your browser information:

User Agent is: Chrome

Challenge: Build a JavaScript Calculator

Link to my current code and project: https://codepen.io/brandon_t1690/pen/MWEJJjW?editors=0011
https://www.freecodecamp.org/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-javascript-calculator

the solution you tried suffers from no way to check if additional operators were already part of your prevNum. I can think of one way that may help without having to modify too much of your existing code:

have a separate state in your code that tracks only the operator, then depending on which you prefer:

  1. either have the operator state have a max possible length of 2 (only when last input operator was a “-”)
  2. or when “-” is the last input, check if an operator exists and if it does, append “-” to the second operand instead of being a part of the operator.
1 Like

Many thanks, I shall try out this solution and tinker a bit with the code after this.

Thank you very much! I got it working now with 16/16 passes thanks to your suggestion!!
My constructor function with the states is now:
constructor(props){
super(props)
this.state = {
lastPress: undefined,
currNum: undefined,
prevNum: undefined,
opArr: []
}
};

with the extra this.state.opArr state added into it as an empty array, and by keeping track of its length can only go at max 2, and the last element can only be the minus operator. I made it so that whenever another operator button is pressed when the length is 2, it slices the prevNum from the beginning till 2 units behind the end, thus removing ALL the present operators and add in a new one. The code now is :

handleClickOp(op) {
const innerOp = op
if (this.state.lastPress == '=') {
this.setState({
lastPress: op,
prevNum: this.state.currNum + innerOp,
currNum: undefined,
opArr: [op]
}) //to start a new calculation after the previous one completed
} else if ((this.state.lastPress == '+' ||
this.state.lastPress == '-' ||
this.state.lastPress == '/' ||
this.state.lastPress == '*')&&op !== '-' && this.state.opArr.length < 2) {
let arr = this.state.prevNum.split("")
let arr2 = arr.slice(0,arr.length-1)
let str = arr2.join("") + op
this.setState({
lastPress: op,
currNum: undefined,
prevNum: str,
opArr: [innerOp]
}) //changes operator when more than one button is pressed at once
} else if ((this.state.lastPress == '+' ||
this.state.lastPress == '/' ||
this.state.lastPress == '*')&&op == '-'&&this.state.opArr.length < 2) {
this.setState({
lastPress: op,
currNum: undefined,
prevNum: this.state.prevNum + op,
opArr: [...this.state.opArr, op]
}) //makes '-' the ONLY exception to be added behind another operator
} else if (this.state.opArr.length < 2) {
this.setState({
lastPress: op,
prevNum: this.state.prevNum + innerOp,
currNum: undefined,
opArr: [op]
}) //nothing special, for first press of operator after number input
} else if (this.state.opArr.length === 2 && this.state.opArr[1] == '-') {
let arr = this.state.prevNum.split("")
let arr2 = arr.slice(0,arr.length-2)
let str = arr2.join("") + op
this.setState({
lastPress: op,
currNum: undefined,
prevNum: str,
opArr: [innerOp]
}) //checks if 2 operators are present and minus is behind it, if it is, the press of a new operator button undoes the 2 previous operators and overwrites them with the 1 new operator pressed.
}
};

MatchaCrisp, thank you so much for your assistance, I wouldn’t be able to do this without your help! Feel free to reply to this thread again if there’s something you feel like there’s anything my current messy code can refine or improve on.

1 Like