skip to Main Content

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


  1. I would expect the dbOpenRequest.onsuccess to be fired only after both stores have been created successfuly

    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.

    Login or Signup to reply.
  2. One small improvement is to review how event listeners work.

    Try changing store.transaction.oncomplete = to store.transaction.addEventListener('complete' , function (event) { ... }).

    When setting oncomplete, this effectively removes all other listeners and just sets one listener. If you set oncomplete twice in a row, only the second listener is registered because the second assignment to oncomplete removes (well, it overwrites) the first. But if you use addEventListener, 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search