Check out a free preview of the full Web Storage APIs course:
The "Using idb with IndexedDB" Lesson is part of the full, Web Storage APIs course featured in this preview video. Here's what you'd learn in this lesson:

Maximiliano demonstrates creating and accessing a database with IndexedDB and improving the process by adding the idb promise-based wrapper. This segment covers database opening, creating, and deleting, keys for data stores, and quick transactions.

Get Unlimited Access Now

Transcript from the "Using idb with IndexedDB" Lesson

[00:00:00]
>> Let's look at the code. This is the standard API, not the one that we're going to use, okay? So this is the API that is available in the browser without any wrapper, without any library. So we need to call indexedDB.open with a name. There is an optional second argument, the version number.

[00:00:17] If you don't provide the version number, it's one. And that's a request, the request to open a database. And then I need to use events like on success, on upgrade, okay, to actually use that database. And the database actually arrives the object in event.target.result. So you need to save that in a global variable.

[00:00:43] So the API looks terrible. Every time you need to open a database and work with it, it doesn't look right, right? So that's why we will use a wrapper, okay? So using a wrapper it's called idb, the one we're going to use. So idb [LAUGH] [INAUDIBLE]. You just open the database like this.

[00:01:07] You say, idb.openDB, you await for it because it's promise-based and you have the object to use, that's all. And if you wanna handle the update event, this is how it looks like. It's idb.openDB, the name, the version, and then we pass an object with an upgrade function. On that upgrade function you will receive the DB object, old version number, new version number, a transaction object, in case you wanna run transactions, and the event.

[00:01:41] You don't need to receive those arguments if you're not going to use them. This is JavaScript, okay? So it looks simpler. We're going to see this in action in a second. Then within the upgrade event, so within that function, we can create object stores. How do we create object store name, that's all?

[00:02:05] What's the object of the table, okay? And there are three ways to create an object store without the key, with a key path, where we express as a string the name of the property that has the key like ID, customer ID, okay? Remember, we are storing objects, so we set the key, or a key generator?

[00:02:29] What's a key generator, an autoIncrement key. So this is like databases, SQL-based database, an autoIncrement, something like that. It's called the key generator. So we don't provide the key, we provide the key generator. And actually we can mix both. We can have a key path, and then key generator.

[00:02:47] That's for weird situations. We can delete the database, okay? We delete DB, that's pretty simple, straightforward. And based on how you are creating the data store, okay, you can have a key path or a key generator, okay? And based off what do you have, this is what you can store.

[00:03:09] For example, if you don't provide a key path or autoIncrement, you can hold any kind of value in that data store, numbers, strings, objects, whatever you want, okay, anything. If you provide a key path and no generator, you can only hold JavaScript objects, that they must have the key path of the ID, the primary key.

[00:03:36] If you provide only this one, it can also hold any kind of value. And there is an automatic generated ID, okay, that we can use later if we want. And if you provide both, okay, if for some weird situations, okay? Because you can only hold JavaScript objects, okay?

[00:03:57] But you have two IDs, two primary keys, the orange generator one and yours. Anyway, it's not common. The most common scenario is typically this one when you provide your key path unless you're storing bytes or something that are not actually objects. Make sense? Again, how much store can you use, one gigabyte.

[00:04:24] You can create as many stores as you want, as many databases as you want up to the quota. Make sense? And as I mentioned before, the wrapper that we're going to use supports quick transactions. In this case, we don't need to create a transaction to then run one query.

[00:04:46] We just say db.add, it will add a value or an object, join a store. Db.put will replace, this is like the update to a key with this value. Delete and clear is delete star, the delete in SQL, okay? Makes sense? So these are very simple APIs, actually, it's not a big deal, okay?

[00:05:14] You put a new object, [INAUDIBLE], it's actually pretty straightforward. And to get the data, okay, you can, for example, count how many objects do you have, async await always. You can get all the objects in one store name, or you can get one object by key, okay? If you have the key, give me the customer with the key one, two, three, that's all.

[00:05:45] So you can see that the API is actually straightforward and simple to use if we're using promises and if you're using this wrapper. For those of you that had experience playing with IndexedDB before, probably you can feel the difference pretty quickly, okay? And because this is async await, this is asynchronously, this won't harm performance a lot.

[00:06:09] The only part where it can harm performance is here. When you are adding or putting new element, this value will be cloned. And that cloning, if it's a really large object for example a Redux state, and your Redux state you're storing everything. I've seen a lot of weird situations like your localization dictionary or the dictionary for all your strings in the Redux state.

[00:06:35] So you have like 200k in your Redux state. Well, if you do that, the cloning will take time. So in that case you need to move that into a worker or split that object into several objects in the store. So instead of writing one large Redux state, you just get a slice and you start different slices.