# How to build a Simple Calculator App with JavaScript

So you’ve learnt the basics of JavaScript and you want to put your new skills to practice by building something. This tutorial provides an exercise in doing just that by describing how to build a simple calculator app.

I will explain each step at a higher level than in my previous tutorials, so if you have trouble following, try doing the Random Quote Machine and Wikipedia Search App tutorials in that order, then come back to this one at a later date.

Also, make sure you complete the previous tutorial which explains how the calculator layout was crafted using CSS Grid. This article focuses only on the JavaScript logic employed to make the calculator work.

Here’s a live demo of the complete project.

## Before you begin

You can find the starting point for this tutorial on JSFiddle. It contains all the necessary markup to build the calculator layout.

The markup is almost identical to the final state of the previous tutorial but I made a few minor changes so go with this one instead.

Start by forking the code to a new fiddle, and follow along by typing each step out all the way to the end. Feel free to do this tutorial on another online playground or on your local machine if you prefer.

## Getting started

Anyone should be able to perform the four most common arithmetic operations (addition, subtraction, multiplication and division) on our calculator by constructing a valid expression using the input buttons, and have the result displayed on the screen.

An example is: `12 + 10`.

To construct a valid arithmetic expression, we need to keep track of a few things: the first operand (`12`), the operator (`+`) and the second operand (`10`).

Let’s start by creating an object to help us keep track of these values.

Type this at the top of the JavaScript pane in JSFiddle:

The `calculator` object holds all the data that we need to construct a valid expression.

• `displayValue` holds a string value that represents the input of the user or the result of an operation. This is what will be shown on the screen.
• `firstOperand` will hold the first operand for any expression. This is set to `null` for now.
• The `operator` key will hold the operator for an expression. Also set to `null`.
• `waitingForSecondOperand` is essentially a flag that checks whether an expression can be evaluated or whether the second operand needs to be inputed.

## Updating the display

Right now, the calculator screen shows nothing. We need to display the value of `displayValue` on the screen (‘0’ by default). We will create a function for this purpose so that anytime an operation is performed in the app, we can always invoke it to update the screen with the contents of `displayValue`.

Go ahead and type this below the `calculator` object:

Our “screen” is really just a disable text input.

We can’t type into it directly with the keyboard, but we can definitely change its value with JavaScript. And that’s what the `updateDisplay` function does.

Now you should see ‘0’ displayed on the screen of the calculator.

## Handling key presses

We have four sets of keys: digits (0-9), operators (+, -, *, /, =), a decimal point (.) and a reset key (AC). Let us listen for clicks on the calculator and determine what type of key was clicked.

Here, we listen for a `click` event on `.calculator-keys`. Since all the keys on the calculator are children of this element, the `click` event filters down to them too. This is known as event delegation.

Inside the callback function of the event listener, we extract the `target` property of the click event using object destructuring which makes it really easy to unpack object properties into distinct variables.

The `target` variable is an object that represents the element that was clicked. If this element is not a button (such as if you click the spaces between the buttons), we will exit the function early.

That’s what the first `if` statement does:

Otherwise, we log the type of button that was clicked as well as its value.

Try it out. Open up your browser console and click any of the buttons. The appropirate key type and value should be logged to the console.

## Inputting the digits

Next, let us make the digit buttons work so that when they are clicked, feedback is displayed to the user on the screen.

Since the `displayValue` property of the `calculator` object represents the input of the user, we need to modify the value of this property when any of the digits is clicked.

Create a new function called `inputDigit` below the `calculator` object.

Next, replace `console.log('digit', target.value);` with the following:

In the `inputDigit` function, we use the ternary operator (`?`) to check if the current value displayed on the calculator is ‘0’ (the default).

If so, we overwrite `calculator.displayValue` with whatever digit was clicked. Otherwise, if the number is a non-zero number, we append to it. Finally we call `updateDisplay()` to update the information on the screen after each button is clicked.

Try it out by clicking any of the digit buttons. The display should be updated with whatever digit you clicked.

## Inputting a decimal point

When the decimal point key is clicked, we need to append a decimal point to whatever is displayed on the screen except if it already contains a decimal point.

Here’s how we can achieve that. Create a new function called `inputDecimal` below `inputDigit`:

Then replace `console.log('decimal', target.value);` with the following code:

Inside the `inputDecimal` function, we use the `includes` method to check if `displayValue` does not already contain a decimal point. Then we append the dot to the number. Otherwise, we do nothing.

Try it out:

## Handling Operators

The next step is to get the operators (+, -, x, /, =) on the calculator working. There are three scenarios to account for:

### 1. When the user finishes entering the first operand and hits an operator

This indicates that he/she is ready to enter the second operand. What we need to do here is store the first operand and update the display with the new string of numbers.

Create a new function called `handleOperator` below `inputDecimal`:

Then replace `console.log('operator', target.value)` with the following code:

When an operator key is pressed, we convert the current number displayed on the screen to a number (`parseFloat(displayValue)`) and then store the result in `calculator.firstOperand` if it does not exist already.

We also set `calculator.waitingForSecondOperand` to `true` which indicates that the first operand has been entered and the second one is ready to begin, and `calculator.operator` to whatever operator key was clicked.

At this point, it is useful to see how the properties of the `calculator` object is being updated on each button press. Add the following code to the end of both `inputDigit` and `handleOperator`.

Now, try to construct a valid arithmetic operation by clicking the following keys in turn: `12 + 10`. Notice that when the `+` key is pressed, the values of `firstOperand` and `operator` is updated to `12` and `+` respectively while `waitingForSecondOperand` is set to true indicating that the calculator is waiting for the second operand (10) to be inputted.

However, there’s a bug here. The second operand does not overwrite the first operand which is currently displayed on the screen. Instead, it is appended to it.

Let’s fix that by updating the `inputDigit` function to look like this:

Here, we check if `waitingForSecondOperand` is `true` and set `displayValue` to the key that was clicked. Otherwise, we perform the same check as before, overwriting or appending to `calculator.displayValue` as appropriate.

Now, try out the expression as before. It should update the `displayValue` properly.

### 2. When the user finishes the second operand and hits an operator

The second scenario we want to handle is if the user has finished entering the second operand and an operator key is clicked. At this point, all the ingredients to perform a valid calculation is present so we need to display the result of the calculation to the user.

After `12 + 10`, let’s say the user hits the `=` button. What should happen?

Well `22` should be presented on the screen as the result of the calculation and the `firstOperand` should be updated to the result so that it can be used in the next calculation.

Update `handleOperator` to look like this:

Then create a new object called `performCalculation` below `handleOperator` with the following properties:

The `else if` block added to `handleFunction` checks if an `operator` already exists. If so, property lookup is performed for the operator in the `performCalculation` object and the function that matches the operator is executed.

This function returns the result which is then stored in the `result` variable. We then display the result to the user by updating the `displayValue` with this result and also set the `firstOperand` to the result.

Try it out. Enter `12 + 10 =` and notice that the correct result is displayed on the screen.

It also works when you chain a string of operations. So `5 * 20 - 14 =` should give `86` as the result.

This is because hitting the `-` key triggers the calculation of the first operation (`5 * 20`) whose result (`100`) then set as the `firstOperand` for the next calculation so by the time we enter `14` as the second operand and hit the `=` key, the function that is defined in the `-` property of `performOperation` is executed giving `86` as the result which is also set as the `firstOperand` for the next operation.

Try out other expressions and confirm that the calculator works as expected.

### 3. When a user enters two or more operators consecutively

It’s quite common to change one’s mind about the type of operation one wants to perform so the calculator must handle this properly.

Let’s say you want to add 7 and 2 together, you will click `7 + 2 =` which will produce the correct result. But let’s assume after hitting `7 +`, you change your mind and decide to subtract 2 from 7. Instead of clearing the calculator and starting all over, you should be able to hit `-` to override the `+` that was previously entered.

Remember that at this point (`7 +`), `waitingForSecondOperand` will be set to `true` since the calculator expects a second operand to be entered after the operator key. We can use this quality to update the operator key and prevent any calculations until the second operand has been inputted.

Modify the `handleOperator` function to look like this:

This is the relevant change:

The `if` statement checks if an `operator` already exists and if `waitingForSecondOperand` has a truthy value. We then update `operator` and exit from the function by using an early `return` statement so that the rest of the function is not executed and no calculations are performed.

Try it out. Click multiple operators after entering some digits and monitor the calculator object in the console. Notice that the `operator` property is updated each time and no calculations are performed until you provide the second operand.

## Resetting the calculator

The final task is to make sure the user can reset the calculator to its initial state by pressing a key. In most calculators, The `AC` button is used to reset the calculator to its default state so that’s what we’re going to use here.

Go ahead and create a new function below `performCalculation` as shown below:

Then replace `console.log('all clear', target.value)` with the following:

The `resetCalculator` function sets all the properties of the `calculator` object to their original values. Now click the `AC` key on your calculator. It should work as expected. You can check the `calculator` object in the console to confirm.

## One more thing…

There’s a bug that allows you to add a decimal point to the `displayValue` after clicking on an operator.

Although this bug does not affect the result of the expression, it’s not ideal for a calculator to behave like that. We can write a fix by making a modification to `inputDecimal`:

Here’s the relevant change:

We prevent the decimal point from being appended to the `displayValue` while `waitingForSecondOperand` is true by using an early return statement just like we’ve done a few times now.

Note that you can execute one statement in an `if` block without enclosing it within curly braces.

Here’s the final state of the calculator:

## Wrap Up

That concludes my tutorial. This calculator can be enhanced in a lot of ways though. Here are a few ideas that you can implement to improve upon what we’ve covered here:

• Add the `%` function.
• Add the square root and square functions.
• Make it possible to clear an entry without resetting the calculator.
• Make it possibe to type in negative numbers (e.g -3).

Take a stab at implementing those features in your application.

If this article helped you in anyway, please consider sharing it. Don’t forget to ask for help in the Gitter chatroom if you get stuck.