Last week I was at KCDC and it was absolutely amazing. I was lucky enough to not only attend, but also to speak about something near and dear to my heart – Offline First techniques. This time I was talking about using IndexedDB.
I’ve written about the importance of offline availability here. Offline First offers a kind way to handle a user’s loss of connection – something over which they have little to no control. And even more than that – implementing Offline First techniques can help people, which I’ve written about here.
Before we dive into any code, let’s talk about IndexedDB’s structure. I think IndexedDB is more similar to NoSQL, rather than traditional relational SQL. So let’s delve into how IndexedDB data is stored.
Each web app can have multiple IndexedDB databases, which are made up of Object Stores. An Object Store is kind of like a table, but it doesn’t use columns. It’s a place to store Objects, which will probably look similar to a server response or ajax request. Later on, we’ll look at some examples.
Within an Object Store, there are Indexes. An Index is a defined property within an Object Store. It’s a little bit like a column, except that it doesn’t have a defined type, nor does it require a type.
Indexes have various properties which can be applied to them. A few common ones include
keyPath. When we apply
autoIncrement to an Index, the Index will create something similar to an auto-incrementing ID in SQL. I mentioned before that Indexes don’t have type requirements, but every rule needs an exception. When we use
autoIncrement our Index will always be a number. However, we don’t need to specify a type for this to happen, nor do we need to pass in a number, as IndexedDB is going to handle that for us.
Another handy property we can apply is
unique allows us to specify whether or not an Index value can be duplicated. So for instance, if we wanted a list of email addresses, we might say that the email Index would be unique. This would keep any duplicates from being added. In the event that someone tries to add an email that is already in our Object Store, the email (and associated record) won’t be added. This helps protect the integrity of the data.
The last property we’ll discuss here is
keyPath property allows us to define a sort of “master” Index within our Object Store. It’s a little similar to a primary key in a SQL table, but like most Indexes, does not require a specified type. Defining an Index as a
keyPath allows us to look up records directly by that property.
Using our email example from before, if we specified the email address Index as our Object Stores
keyPath, we could look up “firstname.lastname@example.org” directly, and get that record. If the
keyPath for a record were a name instead, we would need to look up “Patricia CEO” to find the email address. Specifically, we cannot directly look up records via an Index that has not been defined as a
Now that we have a good idea of IndexedDB’s structure, we’ll look at some code in the next post.