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' });
然后:
- 您还必须指定商店应使用密钥生成器,即
{keyPath: 'id', autoIncrement: true}
,这将为您生成数字密钥(1、2、3、...)并注入到价值观;或者:
- 您存储的值必须已经包含与键路径匹配的 属性,例如
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);
我在 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' });
然后:
- 您还必须指定商店应使用密钥生成器,即
{keyPath: 'id', autoIncrement: true}
,这将为您生成数字密钥(1、2、3、...)并注入到价值观;或者: - 您存储的值必须已经包含与键路径匹配的 属性,例如
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);