Desktop Apps using Electron JS with centralized data control

  •        0
  

We aggregate and tag open source projects. We have collections of more than one million projects. Check out the projects section.



When there is a requirement for having local storage for the desktop application context and data needs to be synchronized to central database, we can think of Electron with PouchDB having CouchDB stack. Electron can be used for cross-platform desktop apps with pouch db as local storage. It can sync those data to centralized database CouchDB seamlessly so any point desktop apps can recover or persist the data.

In this article, we will go through of creation of desktop apps with ElectronJS, PouchDB and show the sync happens seamlessly with remote CouchDB.

Pre-requisites:

Install node and npm latest release with latest distributions. Read the installation guide to install Node.

ElectronJS

Build cross-platform desktop apps with Javascript, HTML and CSS with ElectronJS framework. Thanks to chromium rendering engine and nodejs runtime. ElectronJS source code available in github and it is licensed under MIT license. It has been widely used and testimonials like Slack, WhatsApp desktop application built with Electron framework.

ElectronJS can be installed easily through

   npm install --save-dev electron 

PouchDB

PouchDB is a Javascript DBMS with an API inspired by CouchDB. It is a schema free document store for local small storage. It has been developed by Apache Software foundation under Apache License 2.0 and available in github. It supports master-master and master-slave replication with eventual consistency.

It can be installed through npm packages or can be done by simply invoking

   npm install -g pouchdb
   git clone https://github.com/pouchdb/pouchdb.git
   cd pouchdb
   npm install

CouchDB

CouchDB can be installed remotely as centralized document store. It will be used to authenticate and complete control of all the desktop data. PouchDB and CouchDB seamlessly replicate bi-directionally with Rest API protocol. It is developed by Apache software foundation and licensed under Apache-2.0 license. Source code is available in Github. The Couch Replication Protocol lets your data flow seamlessly between server clusters to mobile phones and web browsers, enabling a compelling offline-first user-experience while maintaining high performance and strong reliability. CouchDB comes with a developer-friendly query language, and optionally MapReduce for simple, efficient, and comprehensive data retrieval.

Installation will be straight walk through of the installation guide in the CouchDB site.

   sudo apt-get install -y apt-transport-https gnupg ca-certificates 
   echo "deb https://apache.bintray.com/couchdb-deb bionic main" | sudo tee -a /etc/apt/sources.list.d/couchdb.list
   sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8756C4F765C9AC3CB6B85D62379CE192D401AB61
   sudo apt update
   sudo apt install -y couchdb

After installation, CouchDB can be opened in the browser using http://127.0.0.1:5984/_utils/index.html#login. Using admin login and create a database as Employee DB.

Build Application

Create a nodejs application with "npm init" with user defined parameters and install Electron and PouchDB. So package.json will look as below

 {
    "name": "firstelectron",
    "version": "0.1.0",
    "description": "first electron for quick start",
    "main": "main.js",
    "scripts": {
          "start": "electron main.js"
    },
   "author": "nagappan subramanian",
   "license": "ISC",
   "devDependencies": {
       "electron": "^6.0.12",
       "pouchdb": "^7.1.1"
  },
  "dependencies": {
      "electron-prebuilt": "^1.4.13",
       "pouchdb-browser": "^7.1.1",
       "pouchdb-find": "^7.1.1"
   }
}

File: main.js

Create main.js file to open the html page in desktop native window.

 //import statements
 const { app, BrowserWindow } = require('electron')

 const path = require('path')

 const url = require('url')

 //global variables
 let win

function createWindow () {
    // Create the browser window.
     win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
          nodeIntegration: true
       }
    })

    // and load the index.html of the app.
    win.loadURL(url.format({
         pathname: path.join(__dirname, 'index.html'),
         protocol: 'file:',
         slashes: true})
    );

    win.webContents.openDevTools();

    win.on('closed', function(){
    win = null;
 });
}

 console.log(app);
 console.log(BrowserWindow);

 app.on('ready', createWindow);

 app.on('window-all-closed', function(){
      //below is for macos to quit all the menu actions also
      if (process.platform!=='darwin') {
          app.quit();
      }
 });

 app.on('activate', ()=> {
       //this is also for macos
    if (win==null) {
       createWindow();
    }
 });

 

File: index.html

index.html file will have the display of employee list and it can be added using the add in header nav. Add happens by using input parameters through modal and add in the ui using the html template.

  <html>
  <head>
   meta charset="utf-8">
  <meta name="viewport" content="width=device-width">

  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css">
  <link rel="stylesheet" href="employeelist.css">
  <script src="node_modules/pouchdb/dist/pouchdb.min.js"></script>
  <script src="node_modules/pouchdb/dist/pouchdb.find.min.js"></script>
  <script src="employeelist.js"></script>
  <title>Organization CRM</title>
  </head>
  <body onload="loadEmployees()">
  <!--banner-->
  <header class="navbar-fixed">
  <nav id="nav" class="primary-color">
  <span id="header-title">Employee Directory</span>
  <button onclick="showAddModal()" class="actionBtnClass"><i class="material-icons">add</i></button>
  <button onclick="syncModal()" class="actionBtnClass"><i class="material-icons">sync</i></button>
  </nav>
  </header>

  <main>
    <div class="row">
     </div>
  </main>
 

 <!-- card template -->
  <template id="employeeCard">
  <div class="card" style="width: 18rem;">
    <img src="https://img.icons8.com/officel/160/000000/user.png" class="card-img-top" alt="...">
    <a class="btn-floating waves-effect waves-light grey verticaltop" onclick="deleteEmployee(currEmpId)">
       <i class="material-icons">delete</i>
    </a>
    <div class="card-body">
    <h5 class="card-title">Nagappan Subramanian</h5>
    <h4 class="card-title">Architect</h5>
    <p class="card-text contact"> XXXXX-X0494 | nagappan08@gmail.com </p>
    </div>
  </div>
</template>


<!-- modal: add a shopping list form -->
<div class="modal">
  <form id="employee-list-add" class="col s12 white" onsubmit="saveEmployee(event);">
  <div class="modal-content">
  <h5>Add Employee</h5>
  <div class="row">
  <div class="input-field col s12">
     <input name="name" type="text" class="validate" placeholder="Name" required />
  </div>
  <div class="input-field col s12">
     <input name="mailId" type="text" class="validate" placeholder="EmailId" required />
  </div>
  <div class="input-field col s12">
     <input name="designation" type="text" class="validate" placeholder="Designation" required />
  </div>
  <div class="input-field col s12">
    <input name="mobileno" type="text" class="validate" placeholder="Mobile Number" required />
  </div>
</div>
</div>
<div class="modal-footer primary-color">
  <button class="btn-flat" type="button" onclick="closeModal()">Cancel</button>
  <button class="btn-flat" type="submit" >Add</button>
</div>
</form>
</div>

<!-- modal: overlay -->
<div class="modal-overlay" onclick="closeModal()"></div>
  <footer class="footerClass">
     <script>document.write(process.platform);</script>
  </footer>
</body>
</html>

Employee list modal will create pouch db with remote async setup with CouchDB.

File: employeelist.modal.js

 var PouchDB = require('pouchdb-browser')

 var db = new PouchDB('employeedb')

 const remote_url = 'http://admin:admin@127.0.0.1:5984/employeedb';

 db.sync(remote_url, {live: true}).on('change', function() {
    console.log("change happened");
 }).on('error', function(){
     console.log("error happened");
});

db.addEmployee = function (employeeObj) {
    employeeObj._id = new Date().toISOString();
    employeeObj.completed = false;
    db.put(employeeObj, function(err, result) {
    if (!err) {
      console.log("successfully add a employee");
      console.log(result);
   }
})
}

module.exports = db;

Employee list having the handlers for add modal, delete employees and load employees.

File: employeelist.js

 const db = require('./employeelist.model.js')

 const remote_url = 'http://admin:admin@127.0.0.1:5984/employeedb';

 const showAddModal = () => {
    console.log(db);
    let form = document.getElementById('employee-list-add')
    form.reset()
    document.body.className += ' ' + form.id
 }

 const deleteEmployee = (empId) => {
    db.get(empId).then(function(empObj){
    db.remove(empObj).then(function(success){
    console.log(success);
    document.querySelector('main .row').innerHTML = '';
    loadEmployees();
  }).catch(function(err) {
      console.log(response);
  });
 })
}

const loadEmployees = () => {
   db.allDocs({
   include_docs: true,
 }).then(function(results) {
   console.log(results);
   results.rows.forEach(function(row){
   console.log(row.doc);
   let empObj = row.doc;
   let empTemplate = document.querySelector("#employeeCard");
   empTemplate.content.querySelector('h5').innerHTML = empObj.name;
   if (empObj.designation !== '') {
       empTemplate.content.querySelector('h4').innerHTML = empObj.designation;
   }

   if (empObj.mobileno !== '' && empObj.mailId !== '') {
         let contact = empObj.mobileno + '|' + empObj.mailId;
         empTemplate.content.querySelector('.contact').innerHTML = contact;
   }
   empTemplate.content.querySelector('a').setAttribute("onclick", "deleteEmployee('" + empObj._id + "')");
      console.log(empTemplate.content.querySelector('a'));
      let clone = document.importNode(empTemplate.content, true);
      document.querySelector('main .row').appendChild(clone);

  });
 }).catch(function(){
    console.log("not able to read the pouch db");
})
}

 const saveEmployee = (element) => {
 console.log(event);
 const elements = event.target.elements;
 const employeeObj = {};
 for (let i = 0; i < elements.length; i++) {
    if (elements[i].tagName.toLowerCase() !== 'button') {
    employeeObj[elements[i].name] = elements[i].value
 }
}
 console.log(employeeObj);
 db.addEmployee(employeeObj);
}

const closeModal = () => {
   let classNames = document.body.className;
   document.body.className = classNames.replace('employee-list-add', '');;
}

The App demo is available in the below video.

 

Reference:

Source code: https://github.com/nagappan080810/employeedesktopapp

https://electronjs.org/

https://github.com/pouchdb/pouchdb

https://github.com/apache/couchdb

https://github.com/ibm-watson-data-lab/shopping-list-electron-pouchdb

 


Sponsored:
To find embedded technology information about MCU, IoT, AI etc Check out embedkari.com.


   

Nagappan is a techie-geek and a full-stack senior developer having 10+ years of experience in both front-end and back-end. He has experience on front-end web technologies like HTML, CSS, JAVASCRIPT, Angular and expert in Java and related frameworks like Spring, Struts, EJB and RESTEasy framework. He hold bachelors degree in computer science and he is very passionate in learning new technologies.

Subscribe to our newsletter.

We will send mail once in a week about latest updates on open source tools and technologies. subscribe our newsletter



Related Articles

Angular Service Workers Usage Guide

  • angular service-worker offline-app

Web developers come across scenarios like web application completely breaks when workstation goes offline. Likewise to get into our application, every time we need to open a browser and then access it. Instead if it is in app, it will be easy to access for end-user. Push notifications similar to email client need to be done through web application. All these are addressed by a magic called service worker.

Read More


Getting Started on Angular 7

  • angular ui-ux front-end-framework

Angular is a platform for building responsive web, native desktop and native mobile applications. Angular client applications are built using HTML, CSS and Typescript. Typescript is a typed superset of Javascript that compiles to plain Javascript. Angular core and optional modules are built using Typescript. Code has been licensed as MIT License.

Read More


Best open source Text Editors

  • text-editor editor tools dev-tools

Text editors are mainly used by programmers and developers for manipulating plain text source code, editing configuration files or preparing documentation and even viewing error logs. Text editors is a piece of software which enables to create, modify and delete files that a programmer is using while creating website or mobile app.In this article, we will discuss about top 7 all-round performing text editors which is highly supportive for programmers.

Read More


Push Notifications using Angular

  • angular push-notifications notifications

Notifications is a message pushed to user's device passively. Browser supports notifications and push API that allows to send message asynchronously to the user. Messages are sent with the help of service workers, it runs as background tasks to receive and relay the messages to the desktop if the application is not opened. It uses web push protocol to register the server and send message to the application. Once user opt-in for the updates, it is effective way of re-engaging users with customized content.

Read More


New Open Source Web Browser Engine from Google and Mozilla

  • browser browser-engine

Web Browser engine used to render the page from HTML, CSS and Javascript. The browsers are one of the most important tool to view the web and it is must have software in Desktop and Mobile. These new browsers will take advantage of tomorrow’s faster, multi-core, heterogeneous computing desktop and mobile architectures.

Read More



Univention Corporate Server - An open source identity management system

  • ucs identity-management-system

Univention Corporate Server is an open source identity management system, an IT infrastructure and device management solution and an extensible platform with a store-like App Center that includes tested third party applications and further UCS components: This is what Univention combines in their main product Univention Corporate Server, a Debian GNU/Linux based enterprise distribution. This article provides you the overview of Univention Corporate Server, its feature and installation.

Read More


ONLYOFFICE Document Server, an online office app for Nextcloud and ownCloud

  • office office-suite word spreadsheet

ONLYOFFICE Document Server is a free collaborative online office suite including viewers and editors for texts, spreadsheets and presentations, fully compatible with Office Open XML formats (.docx, .xlsx, .pptx). This article provides you the overview of ONLYOFFICE Document Server, its features, installation and integration with Nextcloud and ownCloud.

Read More


LucidWorks Vs SearchBlox - Enterprise Search Solution

  • lucene solr searchblox lucidworks enterprise-search

Enterprise search software should be capable to search the data available in the entire organization or personnel desktop. The data could be in File system, Web or in Database. It should search contents of Emails, file formats like doc, xls, ppt, pdf and lot more. There are many commercial products available but LucidWorks and SearchBlox are best and free.

Read More


Quick Start Programming Guide for redis using java client Jedis

  • redis jedis redis-client programming database java

Redis is an open source (BSD licensed), in-memory data structure store, used also as a database cache and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams. This article explains about how to communicate with Redis using Java client Jedis.

Read More


Top 3 color quantization algorithms

  • color-optimization color-quantization algorithm

I have been writing on the desktop image processing application. At the version 1.0, I use the octree color quantization algorithm to reduce image to 256 colors, which is highly memory efficient with each pixel assigned the color at the center of the octree bin in which it falls. On the other hand, generates the palette using the distribution of colors in the image, but it does not consider the frequency of color. This means that if an image is composed of similar colors overall but has many different low-frequency colors or noise, octree's results can be very poor.

Read More


JHipster - Generate simple web application code using Spring Boot and Angular

  • jhipster spring-boot angular web-application

JHipster is one of the full-stack web app development platform to generate, develop and deploy. It provides the front end technologies options of React, Angular, Vue mixed with bootstrap and font awesome icons. Last released version is JHipster 6.0.1. It is licensed under Apache 2 license.

Read More


An introduction to web cache proxy server - nuster

  • web-cache proxy-server load-balancer

Nuster is a simple yet powerful web caching proxy server based on HAProxy. It is 100% compatible with HAProxy, and takes full advantage of the ACL functionality of HAProxy to provide fine-grained caching policy based on the content of request, response or server status. This article gives an overview of nuster - web cache proxy server, its installation and few examples of how to use it.

Read More


10 sites to get the large data set or data corpus for free

  • search test-data large-data-set data-corpus dataset

You may require GBs of data to do performance or load testing. How your app behaves when there is loads of data. You need to know the capacity of your application. This is the frequently asked question from the sales team "The customer is having 100GB of data and he wants to know whether our product will handle this? If so how much RAM / Disk storage required?". This article has pointers to the large data corpus.

Read More


React JS Developer Salary Overview

  • reactjs javascript salary

These days, web development is a need for any business - it attracts huge investments and can kick-start businesses. As for the tools mainly used for development, JavaScript is riding the wave right now. StackOverflow has been naming it the most popular programming language for six years straight. React, as one of the most popular JS libraries is also the first choice for interface developers. It offers some of the best web development tools for mobile and single-page applications.

Read More


All About Multi-Provider Feature of Angular Version 2.0

  • angular dependency-injection multi-providers

The newly introduced concept of dependency injection in Angular version 2.0 makes it an attractive front-end technology all because of one amazing feature called 'Multi-Providers'. In general, it allows the users to attach certain operations by themselves and a few plugin custom functionality which is not required in our mobile app use case.

Read More


Is Unix time end by 2038

  • unix-time year-2038

In 32 bit operating system, Dates are calculated using number of seconds differece between 1 January 1970 and current date. This difference will reset to 00:00:00 on January 2038. This is called year-2038 Bug.

Read More


Lucene Vs Solr

  • searchengine lucene solr

Lucene is a search library built in Java. Solr is a web application built on top of Lucene. Certainly Solr = Lucene + Added features. Often there would a question, when to choose Solr and when to choose Lucene.

Read More


JWT Authentication using Auth0 Library

  • java jwt authentication security

Json Web Token shortly called as JWT becomes defacto standard for authenticating REST API. In a traditional web application, once the user login credentials are validated, loggedin user object will be stored in session. Till user logs out, session will remain and user can work on the web application without any issues. Rest world is stateless, it is difficult to identify whether the user is already authenticated. One way is to use authenticate every API but that would be too expensive task as the client has to provide credentials in every API. Another approach is to use token.

Read More


Getting Started on Undertow Server

  • java web-server undertow rest

Undertow is a high performing web server which can be used for both blocking and non-blocking tasks. It is extermely flexible as application can assemble the parts in whatever way it would make sense. It also supports Servlet 4.0, JSR-356 compliant web socket implementation. Undertow is licensed under Apache License, Version 2.0.

Read More


Thymeleaf - Text display, Iteration and Conditionals

  • thymeleaf template-engine web-programming java

Thymeleaf is a server-side Java template engine for both web and standalone environments. It is a better alternative to JavaServer Pages (JSP). Spring MVC and Thymeleaf compliment each other if chosen for web application development. In this article, we will discuss how to use Thymeleaf.

Read More