Reputation: 18523
In the onupgradeneeded()
event for IndexedDB I am trying to update each record in an object store. In order to update them I need to first preform an async operation but this causes the upgrade transaction to become inactive and I get the error
Failed to execute 'update' on 'IDBCursor': The transaction is not active.
In the follow code I am simulating an async operation with setTimeout()
let openRequest = indexedDB.open('myDb', 1);
openRequest.onupgradeneeded = function (versionEvent) {
let db = versionEvent.target['result'];
let upgradeTransaction = versionEvent.target['transaction'];
if(versionEvent.oldVersion < 1) {
let objStore = db.createObjectStore('sample');
objStore.add('one', '1');
objStore.add('two', '2');
}
if(versionEvent.oldVersion >= 1) {
let getCursor = upgradeTransaction.objectStore('sample').openCursor();
getCursor.onsuccess = (e) => {
let cursor = e.target['result'];
if (cursor) {
setTimeout(() => {
cursor.update(cursor.value + ' updated');
cursor.continue();
})
}
}
}
};
https://plnkr.co/edit/DIIzLduZT1dwOEHAdzSf?p=preview
If you run this plunker it will initialize IndexedDB. Then if you increase the version number to 2 and run it again you will get the error.
How can I update IndexedDB in an upgrade event if my update relies on an async operation?
Upvotes: 6
Views: 717
Reputation: 8365
You need a different approach. Options include:
There are two approaches for the latter. You could do an open()
with no version number, check the version, and then fetch/upgrade if it is lower than desired. Or you can open at the new version and in upgradeneeded abort the upgrade (get the transaction from the request and call abort()
on it) then fetch the data and re-attempt the upgrade.
Upvotes: 7