Introduction
In this article, we will learn how to create or convert an existing application to a Desktop application with Electron framework. The Electron framework allows us to write cross-platform desktop applications using JavaScript, HTML, and CSS. It is built using Node.js and Chromium and is used by Visual Studio Code and other apps.
It supports macOS, Windows, and Linux platforms.
Step 1. Create an Angular application
The first step is to create an angular application using the create application command. Below is the command of the application created for the demo for this article.
ng new desktop-calculator
Step 2. Write an Application Code
We will create a calculator for this article's explanation. Check out the screenshots of the code below.
app.component.html
<div class="container">
<div class="jumbotron col-sm-4 p-2 m-0 bg-inverse mx-auto" style="border: 1px solid lightgray;border-radius: 2%;">
<h1 class="text-center">Angular Calculator</h1>
<label style="font-weight: bolder;">Input</label>
<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>
<label style="font-weight: bolder;">Result</label>
<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-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('7')">7</button>
<button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('8')">8</button>
<button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('9')">9</button>
<button class="btn 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-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('4')">4</button>
<button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('5')">5</button>
<button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('6')">6</button>
<button class="btn 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-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('1')">1</button>
<button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('2')">2</button>
<button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('3')">3</button>
<button class="btn 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-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('.')">.</button>
<button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('0')">0</button>
<button class="btn btn-success col-sm-6 p-1" type="button" (click)="getAnswer()">=</button>
</div>
</div>
</div>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
input:string = '';
result:string = '';
clickNum(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="";
}
}
Run the angular application using the below command.
ng serve –o
The application works fine with the browser. Now let’s convert to the desktop application.
Step 3. Install Electron to Angular application
Command to install the Electron
npm install electron
Check the package.json file that reference is added for the electron.
{
"name": "desktop-calculator",
"version": "0.0.0",
"main": "app.js",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test",
"electron": "electron .",
"electron:build": "ng build && electron ."
},
"private": true,
"dependencies": {
"@angular/animations": "^15.2.0",
"@angular/common": "^15.2.0",
"@angular/compiler": "^15.2.0",
"@angular/core": "^15.2.0",
"@angular/forms": "^15.2.0",
"@angular/platform-browser": "^15.2.0",
"@angular/platform-browser-dynamic": "^15.2.0",
"@angular/router": "^15.2.0",
"@ng-bootstrap/ng-bootstrap": "^14.2.0",
"@popperjs/core": "^2.11.6",
"bootstrap": "^5.3.3",
"electron": "^32.1.0",
"electron-packager": "^17.1.2",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.12.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^15.2.2",
"@angular/cli": "~15.2.2",
"@angular/compiler-cli": "^15.2.0",
"@angular/localize": "^15.2.0",
"@types/jasmine": "~4.3.0",
"jasmine-core": "~4.5.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.0.0",
"typescript": "~4.9.4"
}
}
Step 4. Add JavaScript file reference to the electron
Now add a javascript app.js file at an application root level.
Add the code like the below screen print to the app.js file and set the path for the index.html file generated in the dist folder of the application.
const { app, BrowserWindow } = require('electron/main')
const path = require('node:path')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('dist/desktop-calculator/index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
Step 5. Set the Package.json file
Add/update the “main” key in the config file at the root level. Set the app.js file name as a value to the main key added.
To run the application with the electron framework we need to add a command to the script key of the package.json file. Check out the below screen print for the reference.
Step 6. Run the Application as a Desktop
Once all configuration is done it’s all set to run from the command line or visual code terminal using the below command.
npm run electron:build
After successfully building and running it will open the application as a desktop application. Below is the screen print of the demo application.
It’s all set and we can see our angular application running as a desktop application. So we can say we have installed the angular electron properly. But this is not the exact solution we want. We need an executable file that we can execute directly without execute any command. So let’s check out how we can generate exe.
Step 7. Install Electron Packager
Open the application as a desktop application we need an electron packager. Now close the application and install the packager using the below command.
npm install electron-packager
Step 8. Generate the Application Package
To generate the application package which we can execute directly from the windows use the below command.
npx electron-packager ./ calculatorApp –plateform=win32 –overwrite
Explanation of command
- Npx is used because we have not installed the packager at the global level. To execute at the application level we need to use npx.
- Electron-package is the command to generate the package
- ./ is the directory info where to generate package files.
- The platform is used to set select operating systems like Windows, Mac, or Linux. Here in this demo, we are using Windows so we have selected win32.
- Overwrite is just a command if the package is already generated previously and we want to overwrite it with new changes.
Checkout the directory it should generate a folder with the application name you have mentioned in the command.
Step 9. Run the exe from the folder
Now we are all set and ready with the desktop application version of the angular application. Let’s go to the directory of the generated app package and try to run the exe and check the application result.
Conclusion
In this article, we have learned about the Electron framework. We can use it to create a desktop application of an existing or brand-new application. It supports a cross-platform, we can create desktop apps for Windows, Mac, and Linux from source angular applications.