Friday, 31 May 2024

Browser Cache using IndexedDB Programming With Dexie.Js

 IndexedDB is a JavaScript-based object-oriented databaseIndexedDB is a low-level API for client-side storage of significant amounts of structured data, including files/blobs.

Dexie.js is a lightweight, minimalistic wrapper that provides a straightforward API for developers using IndexedDB.

Features of IndexedDB:

  • IndexedDB is a built-in database, much more powerful than localStorage.
  • Key/value storage: value can be anything, multiple key types.
  • Supports transactions for reliability.
  • Supports key range queries, indexes.
  • Can store much more data than localStorage.

Include Dexie in project:

                         In package.json file, need to include dexie version for download.

"dependencies": {
  "@oracle/oraclejet""~7.2.0",
  "dexie""^3.0.2",
  "knockout-store""^4.0.0",
  "moment""2.26.0",
  "showdown""^1.9.0"
}


Load Dexie Dependency to the pages:

define(['ojs/ojcore''knockout''jquery''dexie'], function (oj, ko, $, Dexie) {
});


Basic workflow with Dexie looks like this:

  • Create and open a database
  • Define and upgrade the schema
  • Start transactions and execute database operations
  • Process the results


Steps:

Step 1:  First, you need to create an instance of the Dexie object. The argument specifies the database name.

let db = new Dexie("customMapAttributeDatabase");

Step 2:   Next specify the schema of the database. db.version() specifies the database version number and returns a Version object. This object provides the stores() method that specifies the database schema (object store, primary key, indexes) for this particular version.

db.version(1).stores({
      voNames: 'voName,columns,expiryDate'
     });

stores() takes an object as the parameter. The keys of this object define the names of the object stores. The value is the schema definition that describes the primary key and the indexes. Each key (object store name) becomes a property of the db object: db.voNames

Step 3: Add data to the schema

let AUTOEXPIRYDURATION =1;//Expiry after 1 day
 
var autoExpiryDate = new Date();
    autoExpiryDate.setDate(autoExpiryDate.getDate() + AUTOEXPIRYDURATION);
 
    db.voNames.add({
        voName: voName,
        columns: JSON.parse(JSON.stringify(data.columns)),
        expiryDate: autoExpiryDate.getTime()
    });

Above, data.columns has the response of REST API call, expiryDate is the key it will tell when to expire the data from indexedDb.

Step 4: Get the stored data

Check if the data is already stored in browser cache.


db.voNames.get({
       voName: voName
   }).then(function (data) {
       //There is cached information for this voName. Use that info to populate instead of fetching new data
       if (data != undefined) {
               //We can add logic based on requirement
       }
       else {
             //Step-3 Logic-REST API call and add data to schema
               
     }
});


Need to add custom logic on page to expire browse cache based on defined property AUTOEXPIRYDURATION (In days).

Add below method call on page load 

self.autoExpiryVONames();

The below are the method definations needed to be added on page.

self.autoExpiryVONames = function () {
 
    var hours = AUTOEXPIRYDURATION  // Expiry Days
    var currentTime = new Date().getTime();
    var array = [];
    db.voNames.each(function (record) {
        let expiryTime = record.expiryDate;
        //let expiryTime = 1580906515000;
        if (currentTime - expiryTime > hours * 24 60 60 1000) {
            self.deleteIndexDbRow(record.voName);
        }
    });
 
}
 
self.deleteIndexDbRow = function (voName) {
    db.version(1).stores({
      voNames: 'voName,columns,expiryDate'
     });
    db.voNames.where("voName").equals(voName)
        .delete()
        .then(function (deleteCount) {
            console.log("Deleted " + deleteCount + " objects");
        });
}


Check in browser developer tools, Application tab-->Storage--->IndexedDB



No comments:

Post a Comment