最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to update in indexeddb instead of override all the data? - Stack Overflow

programmeradmin4浏览0评论

I really enjoyed this very simple use of indexeddb, but I was trying to figure out how to do update.

I have seen that .put is suppose to work for this, but when I have tried this, it would just override all the data for id 12345. What am I missing?

This is what I was using below:

store.put({id: 12345, name: {first: "John", last: "Doe"}, age: 42});

store.put({id: 12345, name: {first: "somethingelse"}, age: 42});

Full code:

      var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB;

      // Open (or create) the database
      var open = indexedDB.open("MyDatabase", 1);

      // Create the schema
      open.onupgradeneeded = function() {
          var db = open.result;
          var store = db.createObjectStore("MyObjectStore", {keyPath: "id"});
          var index = store.createIndex("NameIndex", ["name.last", "name.first"]);
      };

      open.onsuccess = function() {
          // Start a new transaction
          var db = open.result;
          var tx = db.transaction("MyObjectStore", "readwrite");
          var store = tx.objectStore("MyObjectStore");
          var index = store.index("NameIndex");

          // Add some data
          store.put({id: 12345, name: {first: "John", last: "Doe"}, age: 42});
          store.put({id: 12345, name: {first: "somethingelse"}, age: 42});

          // Query the data
          var custInfo = store.get(12345);

          custInfo.onsuccess = function() {
              alert("ID " + custInfo.result.id + " age " +custInfo.result.age + " name " + custInfo.result.name.first+ custInfo.result.name.last);  // => "John"
              // alert(getJohn.result.name.first);  // => "John"
          };

          // Close the db when the transaction is done
          tx.onplete = function() {
              db.close();
          };
      }

I really enjoyed this very simple use of indexeddb, but I was trying to figure out how to do update.

I have seen that .put is suppose to work for this, but when I have tried this, it would just override all the data for id 12345. What am I missing?

This is what I was using below:

store.put({id: 12345, name: {first: "John", last: "Doe"}, age: 42});

store.put({id: 12345, name: {first: "somethingelse"}, age: 42});

Full code:

      var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB;

      // Open (or create) the database
      var open = indexedDB.open("MyDatabase", 1);

      // Create the schema
      open.onupgradeneeded = function() {
          var db = open.result;
          var store = db.createObjectStore("MyObjectStore", {keyPath: "id"});
          var index = store.createIndex("NameIndex", ["name.last", "name.first"]);
      };

      open.onsuccess = function() {
          // Start a new transaction
          var db = open.result;
          var tx = db.transaction("MyObjectStore", "readwrite");
          var store = tx.objectStore("MyObjectStore");
          var index = store.index("NameIndex");

          // Add some data
          store.put({id: 12345, name: {first: "John", last: "Doe"}, age: 42});
          store.put({id: 12345, name: {first: "somethingelse"}, age: 42});

          // Query the data
          var custInfo = store.get(12345);

          custInfo.onsuccess = function() {
              alert("ID " + custInfo.result.id + " age " +custInfo.result.age + " name " + custInfo.result.name.first+ custInfo.result.name.last);  // => "John"
              // alert(getJohn.result.name.first);  // => "John"
          };

          // Close the db when the transaction is done
          tx.onplete = function() {
              db.close();
          };
      }
Share Improve this question edited Apr 16, 2018 at 13:50 Josh 18.7k7 gold badges54 silver badges72 bronze badges asked Apr 15, 2018 at 19:56 SolSol 1,0491 gold badge13 silver badges23 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 6

If I understand your question correctly, then I would point out that calling put is not equivalent to SQL update. You cannot replace only some properties of an object in an object store using a single request. When putting a new object into a store, if another object with the same keypath (id) already exists, that existing object will be replaced, entirely. indexedDB does not modify the existing object in the store, a property at a time, instead it pletely replaces the old object with a new object.

If you want to only replace some properties of an object, use two requests. One request to get the existing object in the store, and a second request to store the modified object. In between the get and put, make changes to the object.

Something like this, pseudocode:

function updateSomeProps(db, id) {
  var tx = db.transaction(...);
  tx.onplete = _ => {
    console.log('finished updating object with id', id);
  };

  var store = tx.objectStore(...);
  var getRequest = store.get(id);
  getRequest.onsuccess = _ => {
     var obj = getRequest.result;
     if(!obj) {
       console.log('no matching object for id, canceling update', id);
       return;
     }

     console.log('loaded object to modify', obj);

     // make some changes to the properties of the object loaded 
     // in memory
     obj.age = 42;
     obj.firstname = 'asdf';
     delete obj.lastname;

     // now store the new object in place of the old object
     console.log('storing new object in place of old', obj);
     store.put(obj);
  };
}

function connectAndChangeStuff(id) {
  var openRequest = indexedDB.open(...);
  openRequest.onsuccess = _ => {
    var db = openRequest.result;
    updateSomeProps(db, 12345);
    db.close(); // optional
  };
}
发布评论

评论列表(0)

  1. 暂无评论