I’ve been on a role when it comes to JavaScript and Couchbase. Over the past few weeks I’ve been creating content revolving around the Angular 2 framework, the JavaScript library PouchDB, and Ionic Framework for mobile. What I haven’t explored yet is Couchbase in a desktop application built with Angular 2.

Two years ago I wrote about using Couchbase in a desktop application using AngularJS 1.0 and Electron, but with technology there might as well have been dinosaurs in that time period. A lot has changed and that once great post deserves a refresh.

We’re going to see how to create a desktop application using Electron that is powered by Angular 2, PouchDB, Ionic 2, and Couchbase.

The Requirements

There are numerous requirements that must be met to make this project a success. They are as follows:

The focus and point of this tutorial is not Ionic 2. However, Ionic 2 has a mighty fine UI layer that will save us time over alternative solutions like Bootstrap or Foundation. Ionic 2 also has Angular 2 baked in. That said, we’ll need the Ionic 2 CLI installed. Node.js is a requirement because of the Node Package Manager (NPM) which we’ll use to gather dependencies.

We won’t be including Couchbase Server in this example, but instead Couchbase Sync Gateway and it’s in-memory prototyping database. It isn’t more than a single line to switch over to Couchbase Server from this example. PouchDB will communicate from our desktop application to Sync Gateway and in the other direction as well.

Configuring Couchbase Sync Gateway

Sync Gateway handles all the data orchestration and needs to be configured on a per application basis. For this particular application we’re going to allow all connecting devices to be able to read and write data.

Such a configuration would look like the following:

In the above sample configuration, we’ll be using a database called example, but it can really be called whatever you want. The configuration should be saved to a file, for example, sync-gateway-config.json.

With Couchbase Sync Gateway downloaded and installed, the configuration can be run as follows:

Sync Gateway can then be accessed from http://localhost:4985/_admin/.

Creating an Ionic 2 Project Destined for the PC

If you saw my previous guide on the topic of Couchbase with Ionic 2 and PouchDB, you’re probably wondering what will be different here. The truth is, nothing really. Ionic 2 applications that don’t use native Android and iOS features can be bundled into Electron applications without issue. However, some optimizations have been made to this application versus the previous.

Electron with Couchbase and Ionic 2

In the above animation you can see a simple todo list Electron application where you can add items to the list and have them sync with Couchbase Sync Gateway and eventually other devices and Couchbase Server.

Let’s start creating that simple example.

Making a Fresh Project with the Dependencies

Before we can start developing the application and packaging it in Electron, we need to create a fresh project with each of the dependencies.

From the Command Prompt or Terminal, execute the following:

With the Ionic 2 project created we need to gather a few dependencies such as Electron and PouchDB. To do this execute the following:

Because this Angular 2 application will be using TypeScript, we are best off using JavaScript libraries with type definitions. However, PouchDB doesn’t have an official set of type definitions, rendering them out of date. We can get by this by including the following dependency:

The above dependency will give us access to the require keyword so we can import JavaScript libraries into our project.

Adding Electron for Desktop Support

With the project created we need to add Electron support. This is done by adding a special JavaScript configuration file that Electron processes at boot.

At the root of your project, create a file called electron.js with the following JavaScript code:

Most of the above code was taken directly from the Electron Starter Template, with the exception of this line:

In the above line we are telling Electron which Ionic 2 page to load when the application starts. While the Electron bootstrapping is done, we need to get it bundled within our build scripts.

Open the project’s package.json file and include this line:

The above line tells Electron which file is the configuration file. It is necessary because maybe you didn’t name your file electron.js like I did. We also need to add a particular script that will build the project and launch it with Electron:

It won’t package the application for deployment in an app store, but it will allow us to test it correctly with Electron on our computer.

At this point we can focus on the Angular 2 code which you may or may not have seen before.

Developing a PouchDB Provider for Angular 2

It is good practice to keep data related code separated from your page logic. In Angular 2 we can accomplish this separation through the use of a shared provider.

To create a provider in Ionic 2, execute the following from the CLI:

You should end up with src/providers/pouchdb-provider.ts or similar. The name isn’t really important as long as you remember what it is.

Open the provider file and include the following TypeScript:

The provider will be injected in various pages and emit changes, hence the Injectable and EventEmitter imports. We are also importing the PouchDB JavaScript library.

The provider will act as a singleton with one database instance open for the duration that our application is open. This setup can be created in the constructor method:

In the constructor method, if the databases isn’t already instantiated we are going to instantiate it, open it, and configure the change events. For every change against the database we will emit them and eventually pick them up by subscribing to the listener.

Say we want to get a particular NoSQL document by its id. We can create a function like the following:

For this particular application, the above method is more useful for our document creation method as we want to see if a document exists before we try to update it:

If the document doesn’t exist, it will be created instead of updated.

Because the goal here is to use Couchbase in our desktop Electron application, we need to have a sync function:

The sync method will take our Sync Gateway hostname and database and do a two-way sync between our local database and the remote database.

Finally we provide a way to obtain and subscribe to the change listener.

The PouchDB provider is done, but it is not ready to be used. To use it in each of our pages we need to add it to the application’s @NgModule block found in the project’s src/app/app.module.ts file. Open this file and include the following:

Essentially we only imported the provider and added it to the providers array of the @NgModule block. Now the provider can be used in our application pages.

Adding the Page Logic for a Functional Application

This particular application only has one screen and that one screen is rather simple. Show a list of data and allow for new data to be input.

Starting with the TypeScript logic, open the project’s src/pages/home/home.ts file and include the following:

We’ve imported several Angular 2, Ionic 2, and custom components into the page and injected many of them into the constructor method. The items array will hold our synchronized data that will be displayed on the screen. The constructor method only initializes our variables.

To load data into our variables we should use the ionViewDidEnter method:

In the ionViewDidEnter method we are starting the synchronization with our Sync Gateway and subscribing to the change events. As changes come in they will be added to the items array. We are using NgZone because change listeners are iffy in Angular 2 and we want to guarantee that the UI is updated correctly.

The insert method is pretty much all Ionic 2 logic:

When the method is called, a prompt will display allowing for user input. When saved, the data will be saved as a document in PouchDB and synced to Couchbase Server.

Designing the User Interface

The UI behind the TypeScript logic is short and sweet. Open the project’s src/pages/home/home.html file and include the following HTML markup:

The UI has an action bar with a button that will execute the insert method when pressed. The content of the screen is a list that displays each element from the items array as a row.

Seeing the Project in Action

There was a lot that we did in the Electron with Couchbase example. I’ve uploaded a working project to GitHub if you’d like to take it for a spin.

Download the project and execute the following command:

The above command restore all the project dependencies. With Sync Gateway running, execute the following to run the application with Electron:

Note that you’ll probably have to change the Sync Gateway host in the src/pages/home/home.ts file to match your hostname.

Conclusion

You just saw how to create a desktop application that syncs with Couchbase. This application is powered by Electron, but uses Angular 2, and PouchDB. While the UI layer was Ionic 2, it didn’t need to be. You could use your own UI framework like Bootstrap or similar. The goal here was more to demonstrate Electron with Couchbase and Angular 2. This guide was a step up from my previous on the topic of AngularJS 1.0 with Couchbase and Electron.

Posted by Nic Raboy, Developer Advocate, Couchbase

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.

4 Comments

  1. When running npm run electron
    The result is an error:

    [19:46:53] ionic-app-scripts 0.0.47
    [19:46:53] ionic-app-script task: “build;”
    [19:46:53] Error: Cannot find module ‘../dist/build;’

    (And this is from your own github example, downloaded, did npm install, and npm run electron).

    Any ideas?

    Thanks 🙂

    1. Hi Martín and Nic,

      I’m getting the same error, using Ionic 2.1.12
      [15:44:02] ionic-app-scripts 1.1.4
      [15:44:02] ionic-app-script task: “build;”
      [15:44:02] Error: Cannot find module ‘../dist/build;’

      Did one of you solved it?

      Thanks 🙂

  2. What version of Ionic are you using? I believe Ionic had major changes between the releases of the current and when I published it.

    The content and logic should remain accurate, but the build command might be slightly different.

  3. Hi,

    First, thank you Nic for this post!

    I got the same error (“Error: Cannot find module ‘../dist/build;’”), and I think it’s because the script “electron” supposes the electron npm module is installed globally.
    With electron installed locally, you should use something like this:
    “./node_modules/.bin/electron .”
    See https://electron.atom.io/docs/tutorial/quick-start/

    So, I changed the electron script with this (I’m under Windows OS):

    “scripts”: {

    “electron”: “ionic-app-scripts build && .\\node_modules\\.bin\\electron .”
    }

    Finally, executing “npm run electron” works for me!

Leave a reply