Menu Close

IndexedDB Manipulation with Dexie — Indexes, Seed Data, and Promises

IndexedDB is a way to store data in the browser.

It lets us store larger amounts of data than local storage in an asynchronous way.

Dexie makes working with IndexedDB easier.

In this article, we’ll take a look at how to start working with IndexedDB with Dexie.

Indexes

We can add and drop indexes as we wish.

For example, we write:

const db = new Dexie("dbs");
db.version(1).stores({
  foo1: 'id,x,y,z',
  foo2: 'id,x,y,z',
  foo3: 'id,x,y,z'
});
db.version(2).stores({
  foo1: 'id,x,z'
});
db.version(3).stores({
  foo2: 'id, x, x2, y, z'
});
db.version(4).stores({
  foo3: null
});

We created the foo1 , foo2 , and foo3 stores with indexes x , y and z .

Then to delete index y from foo1 , we write:

db.version(2).stores({
  foo1: 'id,x,z'
});

To add index x2 to foo2 , we write:

db.version(3).stores({
  foo2: 'id, x, x2, y, z'
});

And to drop table foo3 , we write:

db.version(4).stores({
  foo3: null
});

The populate Event

If we need initial data to be added to our database, we can watch for the populate event and add data initial data in the callback for the event.

For example, we write:

(async () => {
  const db = new Dexie("orders_database");
  await db.version(1).stores({
    orders: "++id,headline,description,statusId",
    statuses: "++id,name,openess"
  });

  db.on("populate", async () => {
    await db.statuses.add({
      id: 1,
      name: "opened",
      openess: true
    });
    await db.statuses.add({
      id: 2,
      name: "cancelled",
      openess: false
    });
    await db.statuses.add({
      id: 3,
      name: "shipped",
      openess: false
    });
    await db.statuses.add({
      id: 4,
      name: "delivered",
      openess: false
    });
  });
})()

to listen to the populate event and add some data when it’s emitted.

Promises

Dexie comes with a promise-based API.

For example, we can write:

const db = new Dexie("friend_database");
(async () => {
  try {
    await db.version(1).stores({
      friends: 'name,age'
    });
    await db.friends.put({
      name: "mary",
      age: 28
    })
    const friend = await db.friends.get('mary');
    const arr = await db.friends.where('name').startsWithIgnoreCase('mary').toArray();
    console.log(arr)
  } catch (error) {
    console.log(error);
  }
})()

We create the friends_database database with the friends table.

Then we add some data to the friends store with the db.friends.put method.

Then we get the data with the db.friends.where method with the column name we’re searching.

startsIgnoreCase lets us search by column by the text it starts with.

toArray returns a promise that resolves to an array of results.

Then we log the data with console.log .

All Dexie async methods return a promise.

For example, if we have:

const db = new Dexie("friend_database");
(async () => {
  try {
    await db.version(1).stores({
      friends: 'name,age'
    });
    await db.friends.put({
      name: "mary",
      age: 28
    })
    const friend = await db.friends.get('mary');
    const arr = await db.friends.toArray();
    console.log(arr)
  } catch (error) {
    console.log(error);
  }
})()

That’s the same as:

const db = new Dexie("friend_database");
(async () => {
  try {
    await db.version(1).stores({
      friends: 'name,age'
    });
    await db.friends.put({
      name: "mary",
      age: 28
    })
    const friend = await db.friends.get('mary');
    db.friends.toArray(result => console.log(result));
  } catch (error) {
    console.log(error);
  }
})()

But the promise is more convenient.

Conclusion

We can add index, add initial data, and use the promise API provided by Dexie.

Posted in JavaScript APIs