Fetching data from our local database is not that different from fetching it from a web server,
instead of reaching out to a web server, we just reach out to our local database
but that's it.
So let's start by writing a function in the db helper file that allows us to fetch data from the database.
For this, in there I'll export a new constant, fetch places, which should do what the name suggests, takes
no arguments and in there of course, I want to reach out to my database and get all places. So I'll copy
that code here from insert place with the promise and so on
but the query will change now and also the arguments, I need no arguments because we'll not inject any
arguments here.
Instead of running insert into, we need to run a different query and that will be a very simple
query, I want to select all places in my places table which is done by running select * which means
I want to get all columns, all fields in this database from places.
Now if you know a bit of SQL, now you could also add a where clause to say where ID greater one
for example and so on but I'll not do it here,
I want to get all places so I'll run this query and leave the rest as it is
and now we just need to go to our actions and make sure we have an action for this.
So first of all, I'll add a new identifier here, a new action
identifier, set places, just as we did in the HTTP module for setting the places we fetched from a server
and with that, I can create a new action creator here where I say load places maybe, where this is the name
and in this action creator, I will return this inner function and I use async await in there,
so this function looks like this, where in the end of course we dispatch an action object where the type
should be set places and where we set all the places we loaded
but of course that's the part that's missing. We get the places by running this fetch places function
which I just defined in the helpers file, in the db file there,
so let's import it from there
and then here in the load places action creator, we can run fetch places like this,
this returns a promise so we can await this
and again we get our db result here.
Now we can also wrap this into a try catch block to make sure we catch any errors that could occur,
so here if we have an error, I will just throw it,
so we need to handle it in the component actually,
I'm not doing that here but you could handle it in the same way you handled it in the HTTP module
for example
and with that here eventually, also in the try block, we can dispatch the places which we fetch. For that
it's important for us to understand how the database result looks like,
so I will console log DB result here so that we can look into it and now I want to execute load places
in my places list screen because that is where I need all the places, right?
So in here, I will import star as places actions from the store folder and there, the places actions file
and we need to dispatch an action, so I will import use dispatch from React Redux and then here we create
that dispatch function by executing use dispatch
and now when this component loads, which we can in the end find out with the help of use effect, I want
to dispatch this data loading action.
So here we can run use effect and in the function that we pass to use effect,
I want to dispatch places actions.loadPlaces,
right, like this. Now that means that for this effect, we have one dependency, that's the dispatch
action which should never change,
so therefore this should only run once when the component is created, which is exactly the behavior I
want here.
So now the load places action should be dispatched when our app starts up and indeed, it did start
up here on iOS already and now also on Android and therefore here in the log, I see some output
and that's the Android log and that's the result from the load places action in the
end. As you see it, that's the result of our database action,
insert ID is undefined because we didn't insert something, we instead just got something.
We have that rows field and that's another object which has an _array field which holds an array
of objects and in the end, that's our place data, right?
This object in here, that's our place data,
it has the address, the ID, imageUri and so on.
So it's in the result in rows and then _array,
that's where our data lives.
So that's what we need in the places actions file here when we dispatch our places that we want to display,
that we want to load into Redux,
that should be dbResult.rows._array.
Now of course, that then triggers the set places actions, so now in the places reducer, we need to care
about this,
so here I add a case, set places,
make sure you import the set places identifier here and in the set places case, I can return a new state
snapshot where my places are basically set to the places I got back from the database
and I do this by setting it to action.places because in my actions file, I have this places key
in the action right
which is the loaded place data
and there I just want to map this array into a new array to transform the data, to transform every single
place into a new place that follows my place model where I for example convert the ID of the place
we loaded to a string which is optional,
I just want to show you how you could also then transform the data if you needed to,
you can do this with the map method which maps this array into a new array.
So there
I do that, I keep the title though, I keep the imageUri and I just don't need address and latitude
and so on right now,
that's also why I'm mapping this so that I can draw up some data,
so now I map this array of places I load into a new array of places where I only care about the ID,
title and imageUri.
Now with that if we save this, we should actually be able to see our places being loaded here on Android,
that one place which we stored before and indeed, here it is. So that's our place,
that's place loaded. With that,
now we can focus on also getting the user location of course.