Tuesday, November 13, 2018

IndexedDB from XPages

Browsers have a few ways of storing data. Most of us have used cookies at one time or another. Local Storage is another. For a project I'm working on, I may need a bit more and this is were IndexedDb come in. It is persistent over different sessions, and can store quite a bit. This is for a mobile web app, so this will be very valuable. This post will give you an idea of how much it will hold.

I found a tutorial, I got it to work, but I needed it to work with the XPage application I am working on. And I got it to. You can see in my code that I am adjusting this tutorial, so the initial credit goes to Matt West. If you go over that tutorial, this post will make a bit more sense. I'm concentrating on integrating it to XPages, not really explaining the ins-and-outs of IndexedDb.

For the IndexedDb, you have to open it. Basically, this is initializing it. In the "indexDBLibDAC" script library, we create a blank datastore. I call it "dacs", and has individual records called "dac". It has a keyPath of "timestamp". This allows the JavaScript object to find and retrieve it. Here is a picture of how it stores data in Firefox, you can find this under "Storage" in the Developer tools.


Versioning is important, so you set a version. If you increment the version, it replaces the datastore, and I have not tested what happens if you move up a version, but it may remove all the data in place.

It has to be opened each time. I do this in a control I have on all the pages called "UtilPollConnection". On window.onload, it opens the IndexedDb, as you can see below, taking from the tutorial. I have the work in the script library. 

window.onload = function() {
  // Display the items.
dacDB.open(refreshDacs);
};

So this creates a blank IndexedDb object/database.  

Now, I need to get the values into the IndexedDB. I have a control called "ccTmpDAC". I wanted to show moving it from XPage fields to the IndexedDB, and I wanted to show it in a simple manner. You can fill out the fields, and click the "Move Cookies" button. This puts the values from classic XPages to something easily reachable by Client Side JavaScript. Once the values are in the cookies, click the "Add to IndexedDb" button. That moves it to the IndexedDb. This is not a super-effecient method, but it's how I build this in steps, and I think helps illustrate the process. In my working app, I'm using a similar process. 

Adding a record to the IndexedDb basically makes a JSON element, and you can see how I map the values from the cookies to the dac entry and store it - again based on the tutorial. You can put in a number of values and get the to the IndexedDb.

My process in this is to store the data for a while, when the device is out of data range and upload when a connection is re-established. The basic framework for that is in place. I'm using some timeouts, and for this version they are not set up correctly. But you can test this with the "Sent to RPC" button. This calls a function that gets the first record and calls a rest with it's parameters. You can do other things, but I think this shows how you can get that to a Java Bean or some other SSJS. Meaning we have made a round trip. From traditional XPages input to getting it back.

The one XPage in the attached database does the entire process.

One note on the JavaScript. When I brought the tutorial over to start making it work in XPages, I got some errors on certain keywords. They would just not compile in whatever version of JavaScript Domino 9 uses. I found this post  which explains that to do. You put the words in brackets and single quotes. So when you have result.continue(); Give you a problem, make it result['continue']();, so that it will compile.

Here is a link to the database I have for IndexedDb in XPages.

Cheers,
Brian