learner999
learner999

Reputation: 195

Get and set a value in Indexeddb

This seems simple but for some reason not working

Requirement is

Seems straightforward but running into issues with onupgradeneeded which never gets called even after manually deleting the DB

Here is the code

  <script type="text/javascript">

    var id = GetItem();     

    if(id == null || id=="")
    {
        //based on some other logic 
        var GID = "test";

        SetItem(GID);
    }

    function GetItem() {

        var result = "";

        try {
               var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB;

                // Open  the database
                var open = indexedDB.open("DB", 1);

                open.onupgradeneeded = function () {
                    var db = open.result;
                    var store = db.createObjectStore("Store", { keyPath: "id" });                      
                };

                open.onsuccess = function () {
                    // Start a new transaction
                    var db = open.result;
                    var transaction = db.transaction("Store", "readwrite");
                    var store = transaction.objectStore("Store");

                     var gid = store.get("GID");
                     result = kid.result.value;

                };

                transaction.oncomplete = function () {
                    db.close();
                };                 
            }
            catch (err) {
                console.error(err.message);
            }          
        return result;
    }

    function SetItem(GID) {
        var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB;
        // Open (or create) the database
        var open = indexedDB.open("DB", 1);
        var transaction = db.transaction(["Store"]);
        var objectStore = transaction.objectStore("Store");
        objectStore.put({ id: "GID", value: GID });
        objectStore.onerror = function (event) {
            console.error(err.message);
        };
        request.onsuccess = function (event) {
            // Do something with the request.result!
            alert(request.result.value);
        };
           transaction.oncomplete = function () {
                    db.close();
                }; 
    }


</script>

Local storage is not an option

Upvotes: 3

Views: 16384

Answers (1)

Tomasz Bubała
Tomasz Bubała

Reputation: 2153

There are some minor issues, but if you wrap your head around them, you can make you code work. Let's take a look at SetItem at first:

var open = indexedDB.open("DB", 1);

This is an asynchronous call - so you have to attach onsuccess and onerror into it before you do something with opened db. Later you reference open as db, but event if it was correct it would still throw error, because open doesn't refer to your db. Here's how I fixed it:

var open = indexedDB.open("DB", 1);
open.onerror = function(event) {
  console.log("Error loading database");
}
open.onsuccess = function(event) {
  var db = open.result;
  var transaction = db.transaction("Store", "readwrite");
  var objectStore = transaction.objectStore("Store");
  objectStore.put({ id: "GID", value: GID });
  /* ....... */
} 

As you can see I also passed "readwrite" to db.transaction. You have to do this when you want to put an object into your database. There are some other minor issues - kid instead of gid. I fixed most of them by going into Chrome Dev Tools console (ctrl+shift+i) and reading error - you can also open (Application -> IndexedDB) and delete it before running code to make sure what is really happening. Remember that every time you make an asynchronous call and want to read the response, you need to read it when it's done. Another example from your code:

var gid = store.get("GID"); // here you make asynchronous call
result = kid.result.value;  // here you're trying to get result immediately

It should look like this:

var gid = store.get("GID");
gid.onsuccess = function(event) { /* ... */ }

IDB's API is not easy and intuitive - i can't recommend you idb enough. This library lets you do IDB, but with promises.

Upvotes: 4

Related Questions