JavaScript Calculator

Nawar Yossef
Jul 29, 2017 · 4 min read

Over the past few days I had so much fun building a Calculator app using JavaScript and some of its related technologies.

You can check my app here: Calculator-online .

Also, here is the GitHub repo: https://github.com/NawarYossef/calculator-app .

I realize that there are things that need improvement and that my application will always be a work in progress. Therefore, any contributions you make to improve my code are greatly appreciated.


I thought that before I talk about some of the challenges I faced throughout the project and how I overcame them, I should first list the technologies and things I learned. So here it is:

  • Bootstrap: I used it to create the calculator interface and buttons and to make a web page responsive.
  • jQuery: by using jQuery methods for event handling and collecting user inputs, I was able to manipulate DOM elements in effective ways.
  • Node.js: I used Node.js functions to write modular code and break up my application to multiple smaller files.
  • NPM: it enabled me to load third party libraries and frameworks such as lodash and Express.
  • Browserify: it was important to use a tool like Browserify in order compile Node.js code for the browser.
  • Express: I used Express to create a server and deploy my app on Heroku

Pseudocode

I realized from the beginning that my goal was not to only build a functioning program but to build an application that offers good user experience. The first thing I did was to try out some calculator apps such as the Google calculator, some android calculator on my phone and a couple of other free online apps. After the research phase, I started writing some user stories which later became a foundation for for my pseudocode:

- Initialize application
- collect Input from user
- Prevent user from entering bad expressions:
No multiple operators in a row
No multiple decimals in one number
No zero digits as first value in a number "043"
No zero digits after operator
- display input on screen
- when user clicks equal "=" sign:
convert "x" to "*" and "÷" to "/"
evaluate expression
- display result on screen
- clear screen for new operation.

Killing BUGS!!

After testing the first version of my app, I realized that there were many cases where incorrect user inputs would lead to bad math expression. So I decided to use regular expressions as my main tool to resolve these conditions.

One example is the leading zeros. I had to find a way to prevent users from entering zero digits at the beginning of a number and/or after operators. Although there were several option to resolve this issue, I decided to use regular expressions:

if (input.join("").match(/[(\-|=|+|x|\/)][0][0]/g)) {
lastInputDelete();
}

Another bug had to do with the minus operator. I had to find a way to prevent the user from entering two operators in succession (e.g.''5 +/ 3'') except when the ''-'' operator which is used to indicate a negative number (e.g. ''5 x -3''). Again, using regular expression was sufficient to resolve this issue:

if (input.join("").match(/[0-9][(x|\/)][(+|x|\/)]/g)) {
secondToLastInputDelete();
} else if (input.join("").match(/[0-9][(x|\/)][(\-)][(x|\/)]/g)) {
twoLastInputsDelete();
} else if (input.join("").match(/[0-9][(+|\-)][(x|\/)]/g)) {
secondToLastInputDelete();
} else if (input.join("").match(/[(x|\/)][(\-)][(\-|+)]/g)) {
lastInputDelete();
}

One of the trickiest bugs was related to how the JavaScript #eval() function does not parse the equal “=” operator as part of an expression and instead returns a reference error :

eval("3* 2* 2 = ")
>> Uncaught ReferenceError: Invalid left-hand side in assignment

And since the user will always enter the equal operator as the last input of an expression, I had to create a method to delete the equal sign before passing the expression to a function where the #eval() method would do its magic:

deleteEqualSign() {
let that = this
$(document).ready(function() {
$("#evaluate").click(function() {
that.lastInputDelete();
});
});
}

Code refactoring

  • After fixing several bugs in the program, it was time to refactor my code. I rewrote some functions to insure that no functions were multi-tasking and that my code is D.R.Y. Instead of using one class that does everything, I used the ES6 #class function to divide my program into two classes:
  • Calculator class: handles collecting inputs, evaluating expressions, display and reset operations.
  • Resolve class: handles validation and incorrect inputs.

One of the main issues I faced when using the #class function is the reference of #this keyword. I had to use an alias (“that”) inside jQuery functions to insure that #this is referencing the class:

displayTotal() {
let that = this
$(document).ready(function() {
$("#evaluate").click(function() {
$("#display").text(screenOutput);
// calling function to reset values for new operation
that.resetForNewOperation();
});
});
}

Deploying to Heroku

This was the most fun part of the whole experience. I first had to learn express to create a server and basic routing. This involved a short learning curve but was overall an extremely rewarding journey. I learned to use the static middleware and use #app.use() function to access the request and response objects:

app.use(express.static(..));
// middleware
app.listen(port, function(){
console.log( "server is up and running on port...")
}

Follow my coding journey here on Medium or find me on GitHub, Linkedin, and Facebook.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade