Handling the calculator controls
→ Click here to see the state of the app after completing this step.
→ Click here to see the changes we'll make in this step in GitHub.
There are three control-buttons that we chose to include in our calculator app. Here's a quick refresher on what they do:
- The
Cbutton ("clear") removes the current inputs and the result. - The
ANSbutton ("answer") let's the user reuse the result of the previous calculation as one of the two numbers in the current calculation. - The
ACbutton ("all clear") also removes all current inputs, but compared to theCbutton it also clears the calculation history. In particular the previous calculation result will also be gone when clicking this button.
Let's start with actually storing the previous calculation result. We therefore extend our state object with another key called previousResult.
3const calculatorState = gg.state( 4 { 5 firstNumber: "", 6 operator: "", 7 secondNumber: "", 8 result: "",+9 previousResult: "", 10 }, 11 { 12 display: (value) =>
Now we can implement the C button. Here we will set the previous result to the current result if there is one. Afterwards we reset all other keys to empty strings.
117 }+118 case "C": {+119 if (value.result) {+120 value.previousResult = value.result;+121 }+122 value.firstNumber = "";+123 value.operator = "";+124 value.secondNumber = "";+125 value.result = "";+126 break;+127 } 128 } 129 return value;
Implementing the AC button is pretty straight-forward. The only difference here is that we also set the previousResult key to an empty string.
127 }+128 case "AC": {+129 value.firstNumber = "";+130 value.operator = "";+131 value.secondNumber = "";+132 value.result = "";+133 value.previousResult = "";+134 break;+135 } 136 } 137 return value;
Now to the last button, the ANS button. If the user clicks it, we want to set the current number to the string "ANS" to signal the user that this number will be replaced with the previous result when calculating. Which number to updated is based on whether there already exists an operator or not. In addition, we can only make use of the ANS button if there already is a calculation result. At last, we don't want to update any number anymore if there already is a calculation result.
135 }+136 case "ANS": {+137 if (value.result || !value.previousResult) {+138 break;+139 }+140 value[value.operator ? "secondNumber" : "firstNumber"] = buttonText;+141 break;+142 } 143 } 144 return value;
When calculating the result we have to now consider the case that one of the numbers (or both) are equal to "ANS". In that case we use the value of the previousResult-key in our state.
90 ) {-const parsedFirstNumber = parseFloat(value.firstNumber);-const parsedSecondNumber = parseFloat(value.secondNumber);+91 const parsedFirstNumber = parseFloat(+92 value.firstNumber === "ANS"+93 ? value.previousResult+94 : value.firstNumber,+95 );+96 const parsedSecondNumber = parseFloat(+97 value.secondNumber === "ANS"+98 ? value.previousResult+99 : value.secondNumber,+100 ); 101 switch (value.operator) {
One more thing: We want to allow the user to override "ANS" again with a custom number. Therefore, if the user presses either a digit from one to nine or the decimal place when the current value of the number is "ANS", we don't append the digit but set the value of the number to the digit.
39 case "9": { 40 if (value.result) { 41 break; 42 } 43 const number = value.operator ? "secondNumber" : "firstNumber";-value[number] += buttonText;+44 if (value[number] === "ANS") {+45 value[number] = buttonText;+46 } else {+47 value[number] += buttonText;+48 } 49 break; 50 } ⋮ 61 case ".": { 62 if (value.result) { 63 break; 64 } 65 const number = value.operator ? "secondNumber" : "firstNumber";-if (!value[number].includes(".")) {+66 if (value[number] === "ANS") {+67 value[number] = buttonText;+68 } else if (!value[number].includes(".")) { 69 value[number] += buttonText; 70 } 71 break; 72 }
Congrats! Our calculator is now fully functional!
To finish the app, we're going to add a list of previous calculation results below the calculator using lists in gg.
Next → Using lists