QuokMoon
QuokMoon

Reputation: 4425

IndexedDB throws an error when adding a new value into database

I created a database in IndexedDb successfully but when I try to add a value into the database, I see the following error:

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

Code snippet:

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);
});

I checked the name of table. That is exactly the same. As well its value respective their keys.

How can I resolve this issue ? Could you please share insight on this error ?

Your help would highly appreciate . Thanks in advance.

Upvotes: 4

Views: 6427

Answers (3)

user3088037
user3088037

Reputation: 93

In my case I got this error when tried to force IndexDB to create a copy of a record in the database by saving a deep copy of the record in which the key was assigned an 'undefined'. Apparently the trick was to delete the property from the object:

 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);

Upvotes: 1

BitZar
BitZar

Reputation: 159

For those who are facing a similar problem with TypeScript properties.

Presume we have this model

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

Let's init the objectStore like this

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

And then we want to save our Model

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

Unfortunately we will receive a

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

That's because as now IndexedDB has problems to interpret our transpiled Model (I don't know why, can it probably be related to tsconfig.json?)

Once we change our model to

   export default class Model {
      public id: number;
   }

And then try to save it, we will achieve a successfully completed transaction.

Upvotes: 0

Joshua Bell
Joshua Bell

Reputation: 8337

When you create an object store with a key path:

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

Then either:

  1. You must also specify that the store should use a key generator, i.e. {keyPath: 'id', autoIncrement: true}, which will cause numeric keys to be generated for you (1, 2, 3, ...) and injected into the values; or:
  2. The values you store must already include a property matching the keypath, e.g. store.put({name: 'foo', id: 1234})

(Also, unique is not a property of object stores, only indexes. Keys are always unique within object stores.)

Upvotes: 4

Related Questions