IndexedDB 在向数据库中添加新值时抛出错误

IndexedDB throws an error when adding a new value into database

我在 IndexedDb 中成功创建了一个数据库,但是当我尝试向数据库中添加一个值时,我看到以下错误:

DOMException: Failed to execute 'add' on 'IDBObjectStore': Evaluating the object store's key path did not yield a value.

代码片段:

let db = new AngularIndexedDB('myDb', 1);

db.createStore(1, (evt) => {
  const objectStore = evt.currentTarget.result.createObjectStore('people', { keyPath: 'id', unique: true });
    objectStore.createIndex("name", "name", { unique: false });
    objectStore.createIndex("email", "email", { unique: true });
  }).then(() => {
    db.add('people', { name: 'name', email: 'email' }).then(() => {
  }, (error) => {
    console.log(error);
  });

}, (error) => {
   console.log(error);
});

我检查了 table 的名字。那是完全一样的。以及它们各自的键值。

我该如何解决这个问题?你能分享一下这个错误的见解吗?

非常感谢您的帮助。提前致谢。

当您使用键路径创建对象存储时:

 const store = db.createObjectStore('people', { keyPath: 'id' });

然后:

  1. 您还必须指定商店应使用密钥生成器,即 {keyPath: 'id', autoIncrement: true},这将为您生成数字密钥(1、2、3、...)并注入到价值观;或者:
  2. 您存储的值必须已经包含与键路径匹配的 属性,例如store.put({name: 'foo', id: 1234})

(此外,unique 不是对象存储的 属性,只是索引。键在对象存储中始终是唯一的。)

对于那些面临类似 TypeScript 属性问题的人。

假设我们有这个模型

export default class Model {
   private _id: number;
   public get id(){
      return this._id;
   }
   public set id(value: number){
      this._id = value;
   }
}

让我们像这样初始化 objectStore

   db.createObjectStore('Models', {
                        keyPath: 'id'
                    });

然后我们要保存我们的模型

   let model = new Model();
   let ts = db.transaction('Models', "readwrite");
   let store = ts.objectStore('Models');
   store.add(model);

很遗憾,我们将收到

DOMException: Failed to execute 'add' on 'IDBObjectStore': Evaluating the object store's key path did not yield a value.

那是因为现在 IndexedDB 在解释我们的转译模型时有问题(我不知道为什么,它可能与 tsconfig.json 有关吗?)

一旦我们将模型更改为

   export default class Model {
      public id: number;
   }

然后尝试保存,我们就实现了一个成功完成的交易。

在我的例子中,当我试图强制 IndexDB 通过保存为键分配 'undefined' 的记录的深层副本来在数据库中创建记录的副本时,我遇到了这个错误。 显然,诀窍是从对象中删除 属性:

 const record: T = JSON.parse(JSON.stringify(r));
 r.key = undefined; // does not work!
 delete(r.key); // works! with autoincrement it forces IndexDB to create a new key
 await datastore.add(record);