简体   繁体   中英

IndexedDB DOM IDBDatabase Exception 11 even after using oncomplete

I am very new to IndexedDB Concepts. I am trying to Store a list of movies in the IndexedDB and retrieve it. But for some reason when i try to retrieve it there is a DOM IDBDatabase Exception 11 in chrome browser. I try to retrieve it by using a simple alert. I also tried to retrieve the data by putting the alert inside an onComplete event, but this too seems to be a failure. Could someone please let me know what wrong i am doing. Below is my code.

const dbName = "movies";
var request = indexedDB.open(dbName, 1);
request.onerror = function(event) {
    alert("Seems like there is a kryptonite nearby.... Please Check back later");
};

request.onsuccess = function(event) {
    var db = event.target.result;
var transaction = db.transaction(["movies"],"readwrite");
var objectStore = transaction.objectStore("movies");
var request1 = objectStore.get("1");
request1.result.oncomplete=function(){
alert("The movie is"+request1.result.name);//This is the place where i get the error
}
};

request.onupgradeneeded = function(event) {
    db = event.target.result;
    var objectStore = db.createObjectStore("movies", { keyPath: "movieid" });
    objectStore.createIndex("name", "name", { unique: false });
    objectStore.createIndex("runtime", "runtime", { unique: false });
    for (var i in movieDataToStore) {
objectStore.add(movieDataToStore[i]);
}};

I still do not know what was wrong with the last program. i re-wrote the above program and it worked like a charm. here is the code. Hope this helps anyone who is stuck with this problem. Also if anyone figures out what went wrong the last time please share your thoughts.

var db; //database will be stored in this value when success is called
var movieDataToStore = [{ movieid: "1", name: "Keep my Storage Local", runtime:"60"},
            { movieid: "2", name: "Rich Internet Conversations", runtime:"45"},
            { movieid: "3", name: "Applications of the Rich and Famous", runtime:"30"},
            { movieid: "4", name: "All Jump All eXtreme", runtime:"45"}];

window.query = function() {
    db.transaction("movies").objectStore("movies").get("1").onsuccess = function(event) {
        alert("QUERY: CThe first movie is" + event.target.result.name);
    };};

window.onload = function() {
    if (!window.indexedDB) {
        window.alert("Your browser doesn't support a stable version of IndexedDB. Such and such feature will not be available.")
    }
else{
    var request = indexedDB.open("movies", 1);
    request.onerror = function(event) {
          alert("Seems like there is a kryptonite nearby.... Please Check back later");
};

    request.onsuccess = function(event) {
    db = this.result;
    query();
    };

    request.onupgradeneeded = function(event) {
         var db = event.target.result;
         if(db.objectStoreNames.contains("movies")) {
              db.deleteObjectStore("movies");
            }
         var objectStore = db.createObjectStore("movies", { keyPath: "movieid"});
         objectStore.createIndex("name", "name", { unique: false });
          objectStore.createIndex("runtime", "runtime", { unique: false });
          for (var i in movieDataToStore) {
                objectStore.add(movieDataToStore[i]);
              }
    };

        }   
};
  1. I think it is bad practice to insert data in the onupgradeneeded context. You should be doing this separately in an unrelated function at some other time. In fact, attempting to insert the data on a database whose version was incremented since last page load will automatically trigger the upgradeneeded event for you.
  2. While many of the online examples shove the database connection handle (your db var) into some global scope variable, this is also a bad practice that will lead to errors down the road. Only access the db var within your callbacks as a parameter. In other words, your openRequest.onsuccess function should pass the db variable to the query function. This also reduces the chances of any garbage collection issues later and leaving database connections open (which the designers of indexedDB allow for, but should generally be avoided).
  3. If your movie ids are integers, it isn't clear to me why you are storing and retrieving them as strings. You can store integer values. You can pass an integer to store.get.
  4. You are using for...in inappropriately. It will work, but for...in is intended for looping over the keys of object literals (like var x = {key:value}). Use a normal for loop or use array.foreach when iterating over your movies array.
  5. As you found out in your fixed code, it is better to use request.onsuccess and request.onerror. There is also a transaction.oncomplete. But I am not sure there is a request.oncomplete. What happens is you are setting the oncomplete property of an IDBRequestObject but this does nothing since the code never triggers it.
  6. DOM 11 usually signals you tried to access a table that does not exist or is in an incorrect state. Usually this happens due to mistakes elsewhere, like onupgradeneeded never getting called when connecting. It is confusing, but given the way your code is setup, basically the db gets created the first time your page loads, but then never gets created again, so while developing, if you made changes, but do not increment your db version, you will never see them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM