So far we're able to write data and we do this in a way which allows us to do it both from the normal
Javascript code in the service worker,
now of course we want to read data too, so that we can actually fetch data from our indexedDB. For that
I'll create a new function which I'll name readAllData and you can of course choose any name you like.
Now in this function, we need to get at least one argument, the store from which we want to read data
and then I simply want to return dbPromise,
so still accessing my database, opening a connection and having access to all the objects stores in
there and just like before,
we of course now chain a then block where we in the function get access to the opened database.
Now the pattern is not that different from before, we create a transaction
first of all because every operation has to be wrapped in a transaction. We do this with the transaction
method on the database,
we define which store we want to open,
so that's the store argument we're getting here
and then the type of transaction.
Now before we used readwrite, here we only want to read so we can use readonly and again, make sure
to not mistype that. Then we can open the store,
so just as before we used the transaction, call object store and open the store we passed as an argument,
so again this store
and finally, we can simply return store get all.
Now one difference you may notice is that before we called store put and return tx complete,
now here we don't need to call tx complete because the transaction will complete but we don't need
to return that to indicate that we need it to succeed,
it's a get data operation, if it for some reason fails, we'd simply get back no data
but we never try to change the database. So database integrity was never in danger and therefore we
can directly return the results
and again if that fails, that's just null, undefined
but if it succeeds, that's good,
we never have that case where we need to wait for transaction to successfully finish.
So we get all the data back and now we can use that of course in our code.
So back in feed.js here, I now want to use it.
Now in the service worker,
I didn't check whether we had access to indexedDB because in service workers, we have
but here in the feed.js file, we might not have that access because maybe we're in a browser
which doesn't support indexedDB, even though we saw that 93% of all browsers already support it
at the point of time I'm recording this,
still, better safe than sorry. Before we used caches here,
now I want to check if indexedDB is available. So for that,
I'll simply check if indexedDB is available in window and make sure to not mistype this, DB are two capital
characters. This make sure that the browser supports it and now in there,
I of course want to access it.
I no longer need to match any cache here or something like that,
instead what I'll do is I'll call read all data which I can only call if we import utility.js
.
So let's go back to index.html and before we import feed, I need to import utility.
I'll do it right after IDB, though you need of course
make sure to keep that order because in utility.js,
we use IDB, so we need to import
IDB first and we need to import utility before we import feed.
So now we import that
and now in the feed.js, we can safely call read all data
and of course I want to read all data from my posts data store.
Now with that, we can call then because read all data returns get all
and that happens to be a promise which resolves once the data was read.
So here, we can use that data,
so in function we get back the data we stored and that data will simply be an array of all the values
we had.
So in there I'll first of all check if we didn't receive the network data yet
because if we did, I don't want to overwrite it with the cache and then I'll simply log from cache again
and output the data we get back and thereafter,
I want to call updateUI with that data.
Now updateUI thankfully already expects an array of data so we should be safe to simply call updateUI
and pass the data to it
and in there, we'll loop through the data and it should be an array already.
Now let's see if that works as expected.
Since I also changed feed.js, I'll simply go back to my service worker and bump up the static
cache version here to make sure we fetch a new version, though it doesn't really matter because I'll
use clear anyways, so clear storage, clear site data and then reload to install and activate. Now as you
can see, we have a problem with utility.js here.
Now the reason for this is that I have a typo in the name, so let's name it
utility, this looks better. Let's make sure I have it correctly in all the imports, utility and in the
service worker, it's also utility.
OK,
so let's quickly clear the storage again and reload and see if that error is gone now, that looks better.
You see from cache, it's an empty array now
because nothing is in the cache yet,
if I reload one more time, it should be written to the cache
and now it should fetch it from the cache too
and you see it is an array which has elements which have exactly the structure we expect them to have.
So now if we go offline, we should still see our card here and we do. Now by the way, here's a bonus
point you can earn,
why does the image still work?
Keep in mind in indexedDB, we only store a link to that image, here
we don't store the full image there, just the link,
so this needs to be fetched from the Internet.
Why does it still work then if we're offline?
Did you figure it out?
The reason of course is our dynamic caching The image here is fetched just like all the other assets we have
in our application
and therefore if we inspect our cache here, the dynamic one, we see that it was simply added to it which
makes sense and which is absolutely the behavior we want.
So that is why we have an offline functioning application here using indexedDB instead of the normal
network here
or instead of the cache we used before.