Aaron Ullal is a Freelance developer at FactoryMind, people & life lover, living in permanent beta.  He is a full stack developer based in the beautiful town of Trento, Italy.

IT passionate for more than 7 years, he’s currently focused on mobile development using NativeScript and designing architectural solutions for complex platforms.

Aaron Ullal

Couchbase is a great tool to persist data inside our app. If you haven’t heard of it, it’s a document object storage that allows you to save your data.

If you are using NativeScript-Angular, there are already some great tutorials on how to get started and some more advanced features. In this article we’ll focus on NativeScript with TypeScript.

What we’ll cover

In this simple article we will see how to save and retrieve some user information by:

  1. Installing Couchbase
  2. Creating a TypeScript class that provides a layer of abstraction on top of Couchbase, making it a lot more easy to use (no complex instructions for data insertion and retrieval)
  3. Implementing the singleton pattern on the class

By the end of the tutorial we’ll be able to use instructions such as

without having to write extensive queries to read and write!

Also, all of the code in this article is available in this GitHub repo. Feel free to clone it and play around.

Without further ado, let’s get started!

Install Couchbase plugin

Let’s create a new NativeScript app using the TypeScript template.

In the root folder of our newly created NativeScript project, let’s give the following command to add the plugin and save it to our dependencies list:

Once the plugin is successfully installed, let’s create a class that we’ll use to store and retrieve the user information we need.

Abstraction layer class

OPTIONAL: It is usually a good idea to create an interface to define the properties we need to include.

Navigate to the app folder of our project and create a models folder. Here we will define our Models.ts file  (app/models/Models.ts):

Once we defined our interface, let’s go ahead and create the class that actually implements it. We’ll call the class UserSettings.

Inside this class we also need to store the information related to our Couchbase database.

Let’s break it down:

In the first two lines we require the Couchbase plugin we previously installed along with the Models module we will use to take advantage of TypeScript’s strong typing.

Then we define some other private properties that we’ll use later:

DATABASE_NAME: This is the name of the database. Make sure it doesn’t contain capital letters (and it’s less than 240 characters).

USER_SETTINGS_DOC_ID: Name of the Couchbase document.

database: This is the instance of the database connector.

_userSettingsDocument: Couchbase is a No document-oriented database. It does not have tables, instead it uses a primary storage entity known as Document. Basically a document is a collection of key-value pairs, where the value can be pretty much anything (string, numbers, arrays, etc.). This is what makes Couchbase the number one solution if you need to store a variety of non-relational data: simplicity and flexibility.

_userSettingsObj: This is the JavaScript object that we will use to sync the information with the Couchbase document.

We will cover why we declared the _instance variable later on when we implement the singleton pattern.

Now that we’ve got that covered, let’s see how our class constructor works:

 

Once again, let’s see in detail what’s going on in our constructor:.

this._database = new CouchBaseModule.Couchbase(this.DATABASE_NAME);

Here we are instantiating Couchbase and telling to which database we want to connect.

this._userSettingsDocument = this._database.getDocument(this.USER_SETTINGS_DOC_ID);

This line tells Couchbase to get us our document (the collection which we use to store our info).

 

 

If our document doesn’t exist yet (e.g., first time), we create an empty Object of type UserSettings and we also create a new document. The second parameter we assign to the createDocument function is the id of the document. If we don’t supply this parameter Couchbase will assign the document a UUID automatically.

Fantastic! Now that our constructor is done, let’s see how we can set and retrieve information about our user.

We’ll set up some getters and setters to achieve just that.

 

As usual, let’s break the code down.

In the getter we do three things:

1) We read data from our document into our object

2) Get the desired value (in this case the username)

3) Return it

Easy peasy :)

In the setter we do the following:

1) We get the latest version of our userSettingsObject reading it from the db

2) We set the username property to the value passed to the function

3) We update our document in the database. Contrary to the createDocument function, the first parameter is the ID of the document and the second is the object itself.

But … why do we need to getDocument first? Why can’t we just update the document with the object?

I’m glad you asked!

Basically, whenever we update a document, Couchbase keeps track of the change. Each document has a _rev property; this value gets updated by Couchbase every time a write operation on the document takes place. If we try to update a document with a an older _rev, Couchbase will reject it.

Singleton pattern

Who doesn’t love design patterns? Today we’ll go ahead and implement a very simple, yet effective one: the singleton. The singleton pattern, when correctly implemented, “restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system,”  which is exactly our case.

Basically we make sure that we only have one instance of our class reading and writing to our database.

How do we do that? A simple way to achieve that is with the following two steps:

1) Making our constructor private (Introduced in ts 2.0)

2) Implementing a getInstance method which returns the current instance if it exists, or a new one if it’s the first call

STEP 1:

STEP 2:

Now we can go ahead and create our getInstance() method which will look something like this:

Great! We have abstracted data and implemented the singleton pattern, let’s go ahead and see how we can use our shiny new UserSettings class.

We will be editing the existing main-page.xml and main-page.ts files.

First, we’ll define some basic UI layout. For this demo we’ll be using  a textfield to get user input, a button to save the value to the db, and a label to display the current value in the database. As you can see, if no data is stored in the database the label will simply display “No data stored in the db.”

This is what our main-page.xml file should look like:

Alright! Now that we’ve got a basic layout we can proceed by adding some logic to the UI.

This is how our main-page.ts file should look:

What have we done? In the first lines we just imported a bunch  of stuff, checking the comments to see what the modules do. Next we have:

This is how we get a hold of our UserSettings class instance.

Moving on, we declared another small class:

As you can see MainPageViewModel extends the Observable class. If you’re not familiar with Observables know that they are basically JavaScript objects that trigger a notification if one of the properties change. You can find out more here.

Our view model has two properties: username (which we bound to our textfield) and dbusername (which we bound to our label). Whenever we create a new instance of our class we assign to dbusername whatever value is present in our userSettings instance, which in turn goes and reads data in our database (remember our get username() getter method?).

This function gets called everytime we navigate to our page. We instantiate our MainPageViewModel class and assign it to the mainPageViewModel variable and we bind it to our page. Plain and simple.

Last, but not least, we define the behavior for the button click:

Once again, very simple: We write to the database whatever value our textfield holds (mainPageViewModel.username is bound to the textfield) and then we go and update the value of dbusername in order to update the label. An image is worth a thousand words, soooo here comes a GIF!

This post is part of the Couchbase Community Writing Program

Author

Posted by Laura Czajkowski, Developer Community Manager, Couchbase

Laura Czajkowski is the Snr. Developer Community Manager at Couchbase overseeing the community. She’s responsible for our monthly developer newsletter.

One Comment

  1. Thanks Laura for the detailed blog.
    Can we have similar blog for Nativescript-vue couchbase on how persist the data ?

Leave a reply