How do I retrieve data from the IndexedDB table on a variable?

advertisements

I have some data in a IndexedDB table that quite simply contains this data:

var Customers = [
   { ssn: "123-45-6666", name: "Andrew", age: 22, email: "[email protected]" },
   { ssn: "555-66-7777", name: "Gail", age: 25, email: "[email protected]" }
];

I then have this function to get data back from the IndexedDB:

function RetrieveTableRows(Table) {
   var returnData = [];

   var db = window.indexedDB.db;
   var trans = db.transaction([Table], "readwrite");
   var store = trans.objectStore(Table);

   var keyRange = IDBKeyRange.lowerBound(0);
   var cursorRequest = store.openCursor(keyRange);

   cursorRequest.onerror = window.indexedDB.onerror;

   cursorRequest.onsuccess = function(e) {
      var result = e.target.result;
      if(!!result == false) {
         return;
      }
      returnData.push(result.value);

      result.continue();
   };    

   return returnData; 

}

I realise that it does not work because the onsuccess function is asynchronous, however I can't my head around a solution.

Simply, I want to be able to write:

var myCustomers = RetrieveTableRows('customers');

and be able to then use the variable myCustomers - is this possible?

I have tried using JQuery.deferred(); method but that didn't seem to work, and I know that I could possibly do something like this:

    transaction.oncomplete = function() {
        ReturnTableRows(returnData);
    };
}
function ReturnTableRows(data) {
   //do something with the array of data
}

but I can't work out how to pass this back to the myCustomers variable.


Using the deferred object you should be able to do something like this

function RetrieveTableRows(Table) {
   var returnData = [];
   //setup deferred object
   var defer = $.Deferred();
   var db = window.indexedDB.db;
   var trans = db.transaction([Table], "readwrite");
   var store = trans.objectStore(Table);

   var keyRange = IDBKeyRange.lowerBound(0);
   var cursorRequest = store.openCursor(keyRange);

   cursorRequest.onerror = window.indexedDB.onerror;

   cursorRequest.onsuccess = function(e) {
      var result = e.target.result;
      if(!!result == false) {
         //when done resolve the promise, you could also do more
         //checking and reject the data so you can handle
         //errors
         defer.resolve(returnData);

         //Make sure we exit the function once we run out of data!
         return
      }
      returnData.push(result.value);

      result.continue();
   };    

   //return the promise
   return defer.promise(); 

}

//########### then to use this ###########

//this is now a promise
var myCustomersPromise = RetrieveTableRows('customers');
var myCustomers;

//action todo when promise is resolved/rejected
$.when(myCustomersPromise ).done(function(data){
   //do something with the data/assign it to you var here
   myCustomers= data;
}).fail(function(data){

});

although i have not actually used indexedDB before so maybe misunderstanding how the query knows it is finished ( I am asssuming result.continue() called the onSuccess again and the result is false when it has gone through all the data) but this is the setup I use when doing anything asynchronously in my apps