Ebad Saghar
Ebad Saghar

Reputation: 1127

How to properly retrieve all data from an IndexedDb in a WinJS Windows 8 app?

I've been googling for a while and have found nothing that can help me. I'm just trying to retrieve all data from an IndexedDB.

Here's what my code looks like so far:

var request = window.indexedDB.open("List", 1);
request.onsuccess = function (event) {
                db = request.result;
                console.log("success: " + db);
            };

request.onupgradeneeded = function (event) {
     db = event.target.result;
     var objectStore = db.createObjectStore("List", { keyPath: "id" });
     for (var i in parsedData) {
          objectStore.add(parsedData[i]);
     }

     console.log("RETRIEVING DATA");
     var transaction = request.transaction("List");
     var store = transaction.objectStore("List");
     store.openCursor().onsuccess = function (e) {
         var cursor = e.target.request;
         if (cursor) {
             console.log("List NAMES == " + cursor.value.Name);
         }
     }

}

Now, there's a couple things that need to be said about this code I have written. First of all, I'm aware that I retrieving information should be in a function of its own (I just wrote it this way for printing/logging purposes only). Second, for some reason, the "RETRIEVING DATA" should at least print to the log -- but it doesn't and I don't know why. Third - and most importantly - I keep getting an error on this line:

var transaction = request.transaction("List");

The error is: JavaScript runtime error: Function expected

Not sure what is causing these 2 problems that I'm having.

Upvotes: 0

Views: 1769

Answers (2)

Josh
Josh

Reputation: 18690

  1. The onupgradeneeded callback is only called when you increment the version parameter to indexedDB.open. You will need to increment, save, and then reload each time you want your example code to run. This should cause the RETRIEVING DATA command to be printed. It would be far easier to test if you did not try and insert/read data within the onupgradeneeded callback function. That way you would not need to increment the database version every time you wanted to test/run the code.
  2. You need to open a transaction using the database object. Right now you state var transaction = request.transaction('List');. request is an IDBRequest. I don't think there is an IDBRequest.prototype.transaction method. What you want to use is IDBDatabase.prototype.transaction. For example, var transaction = db.transaction('List');.
  3. Alternatively to #2, but more complicated, you can use the implicit transaction that is used as part of onupgradeneeded. This is a special VERSION_CHANGE type transaction created automatically by indexedDB that is valid only within the body of the onupgradeneeded callback. VERSION_CHANGE txs support read/write. If you really want to do this, you could use var transaction = event.target.transaction;. I would not recommend this but it is possible.
  4. In your cursor onsuccess callback, it looks like you are not advancing the cursor past the first record. You need to add cursor.continue(); within the if block to continue the iteration.

A simple example of how to avoid having to upgrade the database each time:

function upgradeDatabase(event) {
  var db = event.target.result;
  db.createObjectStore('List', { keyPath: "id" });
}

function addParsedData(parsedData, callback) {
  var request = indexedDB.open('List', 1);
  request.onupgradeneeded = upgradeDatabase;
  request.onsuccess = function(event) {
    var db = event.target.result;
    var tx = db.transaction('List','readwrite');
    tx.oncomplete = callback;
    var list = tx.objectStore('List');
    for(var i in parsedData) {
      list.add(parsedData[i]);
    }
  };
}

function retrieve() {
  var request = indexedDB.open('List', 1);
  request.onupgradeneeded = upgradeDatabase;
  request.onsuccess = function(event) {
    var db = event.target.result;
    var tx = db.transaction('List');
    var list = tx.objectStore('List');
    var getAll = list.openCursor();
    var items = [];
    tx.oncomplete = function() {
      console.log('Got items %o', items);
    };
    getAll.onsuccess = function(event) {
      var cursor = event.target.result;
      if(!cursor) return;
      items.push(cursor.value);
      cursor.continue();
    };
  };
}

// This would connect, create, insert, and then select
addParsedData(parsedData, retrieve);

Upvotes: 1

Dick van den Brink
Dick van den Brink

Reputation: 14499

I don't know why it isn't showing the console.log in your cause. It doesn't work for me with the code above because I don't have the stuff for parsedData, when I comment that out I get log and the error you are giving on the transaction.

That error is because you shouldn't call it is a function. It is already an open transaction and you can just do this: request.transaction.objectStore("<Objectstore>"); for opening a store.

So this probably doesn't fix the console.log issue you are having but it should fix the other part!

Upvotes: 0

Related Questions