I am new to IndexedDB and trying to create a database with many stores in it.
After creating the stores my app can go ahead and add records to it, but I need to be sure that all stores have been created.
I am using this function to do so:
function createDatabase() {
return new Promise((resolve, reject) => {
const dbOpenRequest = window.indexedDB.open('GHCaching', 14);
dbOpenRequest.onupgradeneeded = (event: any) => {
const db = event.target.result;
if (!db.objectStoreNames.contains('myTestStore1')) {
const suppliersObjectStore = db.createObjectStore('myTestStore1', { keyPath: 'ssn' });
suppliersObjectStore.transaction.oncomplete = () => {
//First was created
};
}
if (!db.objectStoreNames.contains('myTestStore2')) {
const customersObjectStore = db.createObjectStore('myTestStore2', { keyPath: 'ssn' });
customersObjectStore.transaction.oncomplete = () => {
//Second was created
};
}
};
dbOpenRequest.onsuccess = (event: any) => {
const db = event.target.result;
console.log('Database opened successfully.');
resolve('success');
};
dbOpenRequest.onerror = (event: any) => {
console.error('Error creating database:', event.target.error);
reject(event.target.error);
};
});
}
I would expect the dbOpenRequest.onsuccess to be fired only after both stores have been created successfuly.
However, //First was created, is NEVER called at all.
How can I create multiple stores in the beginning and get a callback that fires only after all stores have been created?
2
Answers
This is correct.
The problem is that you set the transaction.oncomplete property, but then overwrote it immediately after with a new handler.
This is why you see
//Second was created
called but not//First was created
.One small improvement is to review how event listeners work.
Try changing
store.transaction.oncomplete =
tostore.transaction.addEventListener('complete' , function (event) { ... })
.When setting
oncomplete
, this effectively removes all other listeners and just sets one listener. If you setoncomplete
twice in a row, only the second listener is registered because the second assignment tooncomplete
removes (well, it overwrites) the first. But if you useaddEventListener
, then the first remains even when you add the second.Next, you do not really need to listen to when the version change transaction completes. It is the same transaction for both stores, so you are listening redundantly. There is not a transaction per createObjectStore. Both use the same transaction. So listening twice is redundant. Then, the fact that the success event eventually fires is already an indicator the version change transaction completed, so listening for the version change transaction to complete is in general kind of pointless.