In this guide, we will show you how to create a simple & basic calculator application in Angular. If you are new to Angular you can take a look at our Angular tutorial.
Table of Contents
Create Calculator Application
The first step is to create a new calculator application. We name it as ngCalculator
. You can refer to the tutorial How to Create a new project in Angular
1 2 3 | ng new ngCalculator |
Say yes to CSS & Routing.
Add Bootstrap 4
We will use the bootstrap 4 to style our app. Copy the following code to the index.html
1 2 3 | <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous"> |
Create Calculator Component
Create the calculator.component.ts
& calculator.component.html
under the folder calculator
1 2 3 4 5 6 7 8 9 10 11 | import { Component} from '@angular/core'; @Component({ selector: 'ng-calculator', templateUrl: './calculator.component.html', }) export class CalculatorComponent { } |
Template
Now open the calculator.component.html
Our final screen is going to look as follows
- The first row displays the user input including the operators.
- The second row displays the result as the user type.
- C Clears all displays
x
clears the last input i.e delete/
,X
,-
&+
are our four operators for division, multiplication subtraction & addition- use
.
to enter the decimal numbers =
Calculates and resets the user input.
The Template code is as follows.
We are using event binding to map user clicks to component class.
The pressNum()
captures the number & decimal buttons. The pressOperator()
method captures the /
, X
,-
& +
button clicks. allClear
clears all the inputs. clear()
deletes the last input. getAnswer()
calculates and resets the Calculator again.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | <div class="container-fluid"> <div class="jumbotron col-sm-4 p-2 m-0 bg-inverse"> <h1 class="text-center">Angular Calculator</h1> //Displays the User Input <div class="input-group input-group-sm col-sm-12 m-0 p-0"> <div class="col-sm-12 form-control text-lg-right" type="text">{{input}}</div> </div> //Displays the Results <div class="input-group input-group-sm col-sm-12 m-0 p-0"> <div class="form-control text-sm-right" type="text">{{result}}</div> </div> <div class="col-sm-12 p-1 m-0"> <button class="btn btn-info col-sm-6" type="button" (click)="allClear()">C</button> <button class="btn btn-warning col-sm-3" type="button" (click)="clear()">x</button> <button class="btn btn-secondary col-sm-3" type="button" (click)="pressOperator('/')">/</button> </div> <div class="col-sm-12 p-1 m-0"> <button class="btn btn-lg btn-outline-secondary col-sm-3 p-1" type="button" (click)="pressNum('7')">7</button> <button class="btn btn-lg btn-outline-secondary col-sm-3 p-1" type="button" (click)="pressNum('8')">8</button> <button class="btn btn-lg btn-outline-secondary col-sm-3 p-1" type="button" (click)="pressNum('9')">9</button> <button class="btn btn-lg btn-secondary col-sm-3 p-1" type="button" (click)="pressOperator('*')">X</button> </div> <div class="col-sm-12 p-1 m-0"> <button class="btn btn-lg btn-outline-secondary col-sm-3 p-1" type="button" (click)="pressNum('4')">4</button> <button class="btn btn-lg btn-outline-secondary col-sm-3 p-1" type="button" (click)="pressNum('5')">5</button> <button class="btn btn-lg btn-outline-secondary col-sm-3 p-1" type="button" (click)="pressNum('6')">6</button> <button class="btn btn-lg btn-secondary col-sm-3 p-1" type="button" (click)="pressOperator('-')">-</button> </div> <div class="col-sm-12 p-1 m-0"> <button class="btn btn-lg btn-outline-secondary col-sm-3 p-1" type="button" (click)="pressNum('1')">1</button> <button class="btn btn-lg btn-outline-secondary col-sm-3 p-1" type="button" (click)="pressNum('2')">2</button> <button class="btn btn-lg btn-outline-secondary col-sm-3 p-1" type="button" (click)="pressNum('3')">3</button> <button class="btn btn-lg btn-secondary col-sm-3 p-1" type="button" (click)="pressOperator('+')">+</button> </div> <div class="col-sm-12 p-1 m-0"> <button class="btn btn-lg btn-outline-secondary col-sm-3 p-1" type="button" (click)="pressNum('.')">.</button> <button class="btn btn-lg btn-outline-secondary col-sm-3 p-1" type="button" (click)="pressNum('0')">0</button> <button class="btn btn-lg btn-success col-sm-6 p-1" type="button" (click)="getAnswer()">=</button> </div> </div> |
Component
The component is where we put the calculator logic. We use the selector: 'ng-calculator',
so that we can use the calculator component any where in our code using the <ng-calculator></ng-calculator>
.
Angular Calculator Logic
Every time user click on a number or operand, we append it to the input
variable. For example, if user types 54+200+20, we assign it the input
variable. It makes it easier to use the built in JavaScript function eval
to calculate the result just by invoking eval(input)
.
We need to take care of few issues. For Example user may repeat the operands (54++23). Or a invalid decimal number like 54.23.5 etc. Also eval will throw an error if the number begins with 0
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | import { Component } from '@angular/core'; @Component({ selector: 'ng-calculator', templateUrl: './calculator.component.html', }) export class CalculatorComponent { input:string = ''; result:string = ''; pressNum(num: string) { //Do Not Allow . more than once if (num==".") { if (this.input !="" ) { const lastNum=this.getLastOperand() console.log(lastNum.lastIndexOf(".")) if (lastNum.lastIndexOf(".") >= 0) return; } } //Do Not Allow 0 at beginning. //Javascript will throw Octal literals are not allowed in strict mode. if (num=="0") { if (this.input=="" ) { return; } const PrevKey = this.input[this.input.length - 1]; if (PrevKey === '/' || PrevKey === '*' || PrevKey === '-' || PrevKey === '+') { return; } } this.input = this.input + num this.calcAnswer(); } getLastOperand() { let pos:number; console.log(this.input) pos=this.input.toString().lastIndexOf("+") if (this.input.toString().lastIndexOf("-") > pos) pos=this.input.lastIndexOf("-") if (this.input.toString().lastIndexOf("*") > pos) pos=this.input.lastIndexOf("*") if (this.input.toString().lastIndexOf("/") > pos) pos=this.input.lastIndexOf("/") console.log('Last '+this.input.substr(pos+1)) return this.input.substr(pos+1) } pressOperator(op: string) { //Do not allow operators more than once const lastKey = this.input[this.input.length - 1]; if (lastKey === '/' || lastKey === '*' || lastKey === '-' || lastKey === '+') { return; } this.input = this.input + op this.calcAnswer(); } clear() { if (this.input !="" ) { this.input=this.input.substr(0, this.input.length-1) } } allClear() { this.result = ''; this.input = ''; } calcAnswer() { let formula = this.input; let lastKey = formula[formula.length - 1]; if (lastKey === '.') { formula=formula.substr(0,formula.length - 1); } lastKey = formula[formula.length - 1]; if (lastKey === '/' || lastKey === '*' || lastKey === '-' || lastKey === '+' || lastKey === '.') { formula=formula.substr(0,formula.length - 1); } console.log("Formula " +formula); this.result = eval(formula); } getAnswer() { this.calcAnswer(); this.input = this.result; if (this.input=="0") this.input=""; } } |
pressNum
captures the numbers & decimal points .
and appends it to the input
variable. There are two validations here.
- A number cannot contain more than one decimal place.
- Eval will throw the error (
Octal literals are not allowed in strict mode.
), if the number begins with0
. Hence we remove it.
getLastOperand
returns the last operand. For example, if the user input is 120+57
then the last operand is 57
pressOperator
captures the operators. It again appends it to the input
variable. We make sure that that operator is followed by a number and not another operator (54++)
clear
removes the last input.
allClear
clears everything.
calcAnswer
is where the calculation happens. We check the last character. If it is a decimal point (.
) then we remove it (Example in 95+23.
). We also remove the last character if it is an operator. (Example 95+23+
).
getAnswer
calculates and assigns it to the result to input
variable.
That’s it.
Now open the app.component.html
and add <ng-calculator></ng-calculator>
. Also do not forget to add the CalculatorComponent
in the declaration array of app.module.ts
.
Next Steps
You can improve the calculator and add operators like %
& ±
etc. Also try using the (
& )
.
You can also avoid using the eval
function. In that case you can make use of the algorithm to evaluate arithmetic expressions & Shunting-yard algorithm etc. Also, refer to the ng-calculator
hello, i have coded same as you but in my calculator is not taking number as input but rest all buttons are working fine
please help me to resolve this
ok
Merci pour le tuto,
comment implémenter le modulo ?
merci
This method is missing:
Property ‘getLastNumber’ does not exist on type ‘CalculatorComponent’.ts(2339)
const lastNum = this.getLastNumber()
Thanks for noticing
change it to getLastOperand
Error: src/app/calculator/calculator.component.ts:22:28 – error TS2339: Property ‘getLastNumber’ does not exist on type ‘CalculatorComponent’.
22 const lastNum=this.getLastNumber()
How to solve it?
Thanks
Error: src/app/calcultor/app.calculator.component.ts:24:31 – error TS2339: Property ‘lastIndexOf’ does not exist on type ‘void’.
24 console.log(lastNum.lastIndexOf(“.”))
~~~~~~~~~~~
src/app/calcultor/app.calculator.component.ts:25:23 – error TS2339: Property ‘lastIndexOf’ does not exist on type ‘void’.
25 if (lastNum.lastIndexOf(“.”) >= 0) return;
~~~~~~~~~~~
How To resolve it?
[x: string]: any;