user1358518
user1358518

Reputation: 95

IndexedDB not working in Firefox 29, but in Chrome

I have a problem I have developed 50% of the code on Chrome IndexedDB using your console. However to test this code on Firefox I've noticed that does not work.

The asynchronous functions are not calling this JavaScript Firefox is included on a HTML:

<script src="./js/bdLocal.js"></script>

bdLocal.js:

var db;

function openDB() {
   console.log("openDB ") ;
   var request = indexedDB.open("dblocal",1);
   //db = request.result;

   request.onerror = function(event) {
      console.log("Database error: " + event.target.errorCode);
   };

   request.onsuccess = function(event) {
      console.log("Database onsuccess: " );
      db = request.result;
   };

   request.onupgradeneeded = function(event) { 
       console.log("onupgradeneeded");  

       var db = event.target.result;

       var objectStore = db.createObjectStore("customers", { keyPath: "ssn" });

       objectStore.createIndex("name", "name", { unique: true });
       objectStore.createIndex("email", "email", { unique: true });
       objectStore.createIndex("matricula", "matricula", { unique: false });
   };
}

Upvotes: 1

Views: 1608

Answers (1)

Josh
Josh

Reputation: 18690

You are probably trying to use an asynchronous function synchronously. The examples on the Mozilla website are unfortunately very wrong on this point. Unfortunately, so are several of the examples on HTML5Rocks. The following approach will cause you a lot of problems in any browser:

var unreliableGlobalDatabaseConnectionVariable;
var request = indexedDB.open(...);
request.onsuccess = function() {
  var reliableDatabaseConnectionVariable = request.result;
  unreliableGlobalDatabaseConnectionVariable = reliableDatabaseConnectionVariable;
};

var transaction = unreliableGlobalDatabaseConnectionVariable.transaction(...);
// etc.

indexedDB.open is an asynchronous function. This means many things, two of which are important to point out here:

  1. The global db variable will be undefined up until the point that request.onsuccess executes. Therefore, any attempt to access the global variable before this point in time will not work because at this point in time the variable is undefined. Any code that follows request.onsuccess in the same scope is synchronous, and therefore also potentially before. Even code that is on a new line, farther down, is still before.
  2. Once request.onsuccess finishes, then the global db variable may become closed, null, or undefined, or otherwise useless, at any point in time afterward. It could be 1 nanosecond later, it could be 5 milliseconds later, it could be an hour later, it could be never. There is no guarantee the database connection remains open afterward. In general, the way that some of the people that make indexedDB work inside the browser cause the database connection to be closed some small amount of time after there are no live transactions open on the connection.

Try experimenting with the following approach instead:

var openDatabaseRequest = indexedDB.open(name,version);

openDatabaseRequest.onsuccess = function(event) {
  console.log('Connected');
  var db = openDatabaseRequest.result;

  // Only access the db variable within this function
  // where it is guaranteed to be defined and open 
  // for the scope (all statements inside) of this function. For example,
  // do puts and gets and open cursors only inside this 
  // function.
  var transaction = db.transaction(...);
  var store = transaction.objectStore(...);
  var request = store.put(...);
  request.onsuccess = function() {
    console.log('put was successful');
  };
};

This question is probably a duplicate of:

This question is actually unrelated to indexedDB, but related to the use asynchronous code in Javascript. It is therefore probably a duplicate of the hundreds of questions about using XMLHttpRequest.

Upvotes: 2

Related Questions