IndexedDB and Limits - IE

Last week I blogged about maxing out the database size on your browser with IndexedDB, but I didn't test with IE. This morning I did, and unfortunately, it looks like IE does the same bad thing it does with LocalStorage (see my post for details).

I discovered that IE11 would silently fail on adding LocalStorage data when the storage limit was reached. Even worse, you could set, and read data that wasn't actually stored. I slightly modified my code from the previous post to make it a bit more verbose. Here is the new version - I'll point out what's new below.

<!doctype html>
<html>
<head>
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height" />
</head>

<body>

<script>
var db;
var dbname = "bighonkingtest2";
var storename = "crap_new";

imgurl = "baby.jpg";

function urlTo64(u, cb) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', imgurl, true);
  xhr.responseType = 'blob';

  xhr.onload = function(e) {
    if (this.status == 200) {
      // get binary data as a response
      var blob = this.response;
      var reader = new FileReader();
      reader.readAsDataURL(blob);
      reader.onloadend = function() {
        base64data = reader.result;
        cb(base64data);
      }
    }
  };
  xhr.send();

}

function indexedDBOk() {
    return "indexedDB" in window;
}

document.addEventListener("DOMContentLoaded", function() {

    //No support? Go in the corner and pout.
    if(!indexedDBOk()) return;

    var openRequest = indexedDB.open(dbname,1);

    openRequest.onupgradeneeded = function(e) {
        var thisDB = e.target.result;

        console.log("running onupgradeneeded");

        if(!thisDB.objectStoreNames.contains(storename)) {
            thisDB.createObjectStore(storename, {keyPath:"id",autoIncrement:true});
        }

    }

    openRequest.onsuccess = function(e) {
        console.log("running onsuccess");

        db = e.target.result;

        console.log("Current Object Stores");
        console.dir(db.objectStoreNames);

        //Listen for add clicks
        document.querySelector("#addButton").addEventListener("click", addData, false);
        document.querySelector("#countButton").addEventListener("click", countData, false);
    }

    openRequest.onerror = function(e) {
        //Do something for the error
    }


},false);


function addData(e) {
    console.log("About to add data");

  urlTo64(imgurl, function(s) {
    //Get a transaction
    //default for OS list is all, default for type is read
    var transaction = db.transaction([storename],"readwrite");

    transaction.oncomplete = function(e) {
        console.log("transaction onsucc");
        console.dir(e);
    }

    transaction.onerror = function(e) {
        console.log("transaction onerr");
        console.dir(e);
    }

    //Ask for the objectStore
    var store = transaction.objectStore(storename);

    //Define data
    var data = {
        img:s
    }

    //Perform the add
    var request = store.add(data);

    request.onerror = function(e) {
        console.log("Error",e.target.error.name);
      console.dir(e);
        //some type of error handler
    }

    request.onsuccess = function(e) {
        console.log("Woot! Did it");
    }
    
  });

}

function countData() {
    var transaction = db.transaction([storename],"readonly");
    var store = transaction.objectStore(storename);
    var req = store.count();
    req.onsuccess = function(e) {
        console.log(req.result + " items.");
    }
    req.onerror = function(e) {
        console.log("error getting count", e);
    }
}
</script>

<button id="addButton">Add Data</button>
<button id="countButton">Count Data</button>

</body>
</html>

The first change was to set both the db and objectstore name to variables so I could quickly change them. I then added error/complete handlers to the transaction that handles adding data. Finally, I added a simple "count" method.

To test, I loaded the page up and clicked like crazy. I noticed that at 31 items, the count stopped updating. Here is where things got bad. Before this limit, my transaction complete handler did run. After I hit it, the success handler stopped running, but the onerror method never ran!

I modified the objectStore name and confirmed that in a new store, I could still successfully add data (according to the event handlers) but count was stuck at 0. I had to clear my data in IE settings to get it to let me add data again.

I'll file a bug report for this as soon as I can, but I honestly don't know what to suggest. You could add a timeout call in the add functionality to check for a global variable set in your transaction success. If not set, then it didn't fire and you can assume it failed. That feels quite hackish though.

But hey - this is still better (kinda) than mobile Safari, so, yeah, there's that. ;)

Like This?

If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can also subscribe to the email feed to get notified of new posts.