4.2 Storing and Retrieving Data With IndexedDB
If we're offline, we need to store the changes the user makes so that we can send them as updates when they're back online. IndexedDB is perfect for PWAs, and we'll look at one of the ways we can use it in this lesson.
1.Introduction1 lesson, 02:03
2.Getting Started4 lessons, 34:07
3.Caching Resources5 lessons, 40:57
4.Background Sync3 lessons, 23:35
5.Notifications2 lessons, 21:35
6.Making the Application Installable1 lesson, 08:14
7.Conclusion1 lesson, 01:07
4.2 Storing and Retrieving Data With IndexedDB
In the previous lesson, we started adding to our offline experience so that when we are offline, we can actually mark our tasks to be updated. So that if we need to complete one, or if we need to not complete one, we should be able to do that and then rely upon background sync to send that information whenever we are online. So since we are going to be working with data. We need an id for our tasks, because we need to be able to identify each individual task. And we should have had this to begin with. So we'll just fix that now. So we'll just add an id to each one of these fields. Make sure that they are unique, and that is going to be just fine. So with that done we can focus on our code. All right, so we are using IndexedDB, which is an asynchronous data store. And our library is, of course, asynchronous as well. So that means we're going to be using promises. So I want to write the code that I want to write first of all and then we will implement that. So this part of our logic is where we are taking out a task from our marked array. So we are essentially changing our mind in this particular case, we have marked one, but now we decided that we don't want to mark that one. So in that case, we want to remove it from the database. So we'll just call this remove from Db and we will pass in the id of the task. And this is a promise. So when it's done, then we will update the UI. I don't see any reason why we should update the UI and then update the data store. I believe our UI should be dependent upon what we have in our data store and it makes sense to me to change the UI only when our data store changes. So as far as our code is concerned, that's what I want, and we will essentially do the same thing whenever we add an item to be updated. So in this case, though, we will call this function add to Db, and we need to pass in the id of the task as well as the new value. We don't really need anything else because all we care about is the id of the task and if it's complete or not. And then when that is done, we will push in the tasks to our marked array. And there we go. All right, so we just need to write those functions. So let's start with the removeFromDb, that's going to have the id of the task, and we are going to have a function to get the information from the data store. Because in order to work with what we have in our database, we have to first of all fetch it, we have to get it out so that we can work with it and then put it back in. So we're gonna get our value and then we get to work with that value. And in this particular case, we essentially wanna do essentially what we did for removing an item from the marked array. We need to find the index inside of our value which is going to be an array where the object has an id equal to the id that was passed to this function. And if it is greater than 1 or -1 then of course we want to remove it. So we will just call splice. We will pass in the index and 1 and then we want to save the newly updated array. So we will have a function called setDbValue and we will pass it in. So that looks pretty simple to me. Let's write the add to Db function where we are essentially going to start off the same way because we once again want to fetch the information from our data store so that we can work with it. So let's just go ahead and let's just grab what we have for removed from Db and paste that in. Of course, we're going to need to make a few changes here such as we will use our Val variable and then we are going to push in an object that has the id and complete and then we will save that value. So pretty simple stuff there. So we just need to write the functions for getting and setting values. And this is where we get to use the idbikey Val object. That's kind of a mouthful to say. But this has a get method where we pass in the key associated with our value, and for the lack of a better term, I'm just gonna use changed. And then now if we are getting the value, there is the chance that we haven't ever saved a value. So therefore, val would be empty, in which case we would need to at least return an empty array. That way we always have something to work with. And then for our setDbvalue, we already have that value. So we just want to use idbkeyval, and we're gonna call the set method. We need to use the same key, and then we will pass in our array there. And there we go, that should work just fine. So we should be able to go to the browser, let's clear out all of the storage. And let's do a hard refresh just so that everything is loaded and make sure that you are online. So let's do a hard refresh. There are no errors in the console, that's good. Now, IndexedDB doesn't have anything here yet. But that is to be expected. We haven't saved anything. So let's go offline. And let's just click on any one of these and we can see that IndexedDB, automatically updated. There's something here. So we can drill down into the key value store. And we have a key of change. And then we have a value of an array that has just one item with an id of one. Now, as I mentioned in the previous lesson, this is much more robust than just local storage because local storage, it's useful but you can only store strings inside of it. Well here we can actually store objects so we don't have to serialize anything or deserialize anything. We just store an array, and we have an array there. Well, let's click on one of these other ones. Let's do develop application. And we can see in the top right hand corner that data may be stale. So any change that you make while you have IndexedDB open, it's not going to automatically refresh you have to refresh for it. But whenever we do we see that now we have an array of two items, id 1 and the id of 3. And if we click on any one of those two to take it out, when do we need to refresh, but now we have an array of just one item. So we now have our IndexedDB ready to go. We have our data stored so that in the next lesson we can use background sync to send that information to the server whenever we go online.