‫Let's now go back
‫to some more advanced Redux Toolkit
‫and in particular, we will now create a Thunk middleware
‫by using the built-in CreateAsyncThunk function
‫which is a way of creating a Thunk
‫that we avoided when we first learned about Redux,
‫and the idea here is to implement the feature
‫where our users can use geolocation
‫in order to get their GPS position and their address.
‫So let's close these cartSlice
‫which we no longer need
‫and let's open up the userSlice,
‫and so here we already have some pre-written code
‫which we now need.
‫So let's uncomment it.
‫Then we need to take this one
‫and place it at the very top,
‫and then let's also import this getAddress.
‫So import getAddress from
‫and up another one,
‫and then it's inside services and apiRestaurant.
‫Or actually of course, it is
‫in apiGeocoding, so that's correct.
‫So let's analyze what we have here.
‫So we have dysfunction here called fetchAddress
‫which, as the name says,
‫is responsible for fetching some information
‫about the user's address
‫and it does so in two steps.
‫So first of all, it gets the user's geolocation position
‫which is provided by this getPosition function right here.
‫So basically wrapping a promise
‫around this function right here.
‫So then we can use await.
‫So here we get the user's position
‫and then with that position, so that latitude and longitude,
‫we use this reverse geocoding API.
‫So this one right here, let's open that,
‫and so here all we do is to make a fetch request
‫to this API right here
‫with the user's current latitude and longitude.
‫And so this will then do reverse geocoding
‫which is basically getting some information
‫about that GPS position like the city or the street name.
‫So things like that,
‫and so then we can display that information
‫later in the form.
‫So basically what we will want to do,
‫so let's just go back to our order form.
‫And so the idea here will be to be
‫that we have a button here where the user
‫can request their geolocation position
‫and then this filter
‫will automatically be filled with their address,
‫and so that address will come here from this API.
‫So then here we create a nice string
‫based on the information received there
‫and then we return an object,
‫both with the GPS position and the address string.
‫Now okay, so this is just an overview
‫of how this function works,
‫but as we can see,
‫this is an async function
‫which means that we cannot just call this function
‫directly inside a Redux reducer
‫because remember Redux is by nature completely synchronous,
‫and so that's why we now need to talk about Thunks again.
‫So we learned all about Thunks back in the Redux section
‫which you can of course revisit and review,
‫but basically all you need to know at this point
‫is that a Thunk is a middleware
‫that sits between the dispatching
‫and the reducer itself.
‫So it will do something to the dispatched action
‫before actually updating the store.
‫Now back then when we wanted
‫to use Thunks with Redux Toolkit,
‫we manually created our own action creator
‫and placed the Thunk in there
‫so instead of using Redux Toolkit's
‫native way of creating a Thunk,
‫but now let's actually do that.
‫And so now in order to create a Thunk,
‫we will use the createAsyncThunk function.
‫So that sounds like a lot,
‫but let's just do it.
‫So let me do that right here.
‫So here let's create again fetchAddress
‫because we will now again, remove that one,
‫and so this fetch address will be the result
‫of calling createAsyncThunk.
‫And so this createAsyncThunk receives two things.
‫First, we need to pass in the action name,
‫so that's gonna be user and then fetchAddress
‫and then second, we need to pass in an async function
‫that will return the payload for the reducer later.
‫So this function needs to return the promise
‫and so an async function is ideal here.
‫So let's just create an anonymous function here
‫and then grab all this code
‫and place that in there.
‫So then we can remove this
‫and paste that here.
‫All right, and now this fetchAddress here
‫will actually become the action creator function
‫that we will later call in or code,
‫and so let's export this one as well.
‫So now besides this updateName action creator,
‫we also have this new one here which is fetchAddress
‫and we should not call it something like getAddress
‫because those names are reserved for selectors.
‫So by convention, these names for the AsyncThunks
‫should not be called something with get, okay?
‫Now this is I guess pretty confusing,
‫so let's just quickly recap what we did here.
‫So this time we used the Redux Toolkit way
‫of creating a Thunk function.
‫So we called this function right here
‫where we passed in the action type name
‫and so that's this one right here
‫which we will never manually use,
‫but still Redux needs this internally.
‫And then as a second argument,
‫we pass in the actual Thunk function,
‫so the code that we want to execute
‫as soon as this action here will be dispatched.
‫Now what's special about this is that this createAsyncThunk
‫will basically produce three additional action types.
‫So one for depending promise state,
‫one for the fulfilled state,
‫and one for the rejected state.
‫And so now we need to handle these cases
‫separately back in our reducers
‫and so this is how we then connect this Thunk
‫with our reducers down here.
‫So let's do that
‫and here the syntax is actually pretty confusing again.
‫So here we need to now specify these extra reducers
‫which will then get something called a builder.
‫So this is basically a function here
‫and then on this builder we call addCase.
‫So again, pretty confusing here,
‫but this is just the way Redux Toolkit works
‫and it's the reason why I didn't show you this earlier.
‫But anyway, here now let's use
‫that function that we just created, so that fetchAddress,
‫and then here we are going to handle the pending state.
‫So .pending, and then here is where the actual reducer
‫finally comes into play.
‫So here we can now get the state and the action again
‫and so here what we will want to do is to update the state
‫by setting the status to loading.
‫Okay, and so let's actually now update
‫also our initial state.
‫So besides this username,
‫we now need a few more things here.
‫So let's start with a status
‫and let's make it by default idle.
‫And then as soon as we start loading,
‫so that's this pending state,
‫we set it to loading right here.
‫Just place this into these curly braces
‫and then we also want to store the user's position.
‫Let's start here with this empty object, the address,
‫and also some possible error.
‫Okay, and so let's now handle the other two cases.
‫So for the fulfilled state,
‫so the case when there is success,
‫and also the rejected state for an error.
‫So builder.addCase fetchAddress.fulfilled
‫and then again, finally our reducer.
‫So state and action
‫and here we have this small problem
‫where actually we need to change this here
‫after the other at case.
‫So first of all, let's set the status then back to idle
‫and here I'm again forgetting this dot here.
‫Then let's actually take care of the important part.
‫So as I mentioned earlier,
‫this data that we return here
‫will become the payload of the fulfilled state.
‫So payload of the fulfilled state.
‫All right, and so let's then use that.
‫So let's do state.position
‫will be equal to the action.payload.position
‫and then state.address will be
‫equal to action.payload.address.
‫And finally, let's add a case for a possible error.
‫So for example, when the user doesn't accept geolocation,
‫so state and action maintained here.
‫Let's do state.status will be an error
‫and not like this, and state.error.
‫So here we will then also have an error string
‫which actually gets automatically placed on the action.
‫So action.error.message.
‫Now okay, so we actually finished this part here.
‫But before we review this to make this a bit less confusing,
‫let's quickly add just a temporary button right here
‫in this create order so that we can dispatch an action
‫and then actually see this working.
‫So let's create a button here
‫with the onClick handler
‫where we then put this patch.
‫And so let's actually get that.
‫I think we don't have it yet.
‫Let's just do that somewhere here.
‫So use dispatch, and so here what we want to dispatch
‫is exactly this action creator.
‫So we want to dispatch an action that is created
‫by this action creator that we just made here
‫and so that will then basically dispatch an action
‫with this string here,
‫so with this action name and attached the pending state
‫and the fulfilled and the rejected state.
‫So that's why we exported that
‫and so let's see if this works.
‫So get position like this,
‫but then we need to add some pizza here
‫actually to the cart first.
‫All right, and now let's actually open up
‫our Redux dev tools again.
‫So that's gonna be really handy here
‫and so let's click here,
‫and so something is definitely working.
‫So it's asking me here to allow geolocation,
‫so let's allow that.
‫And you see that a lot of things happened down here,
‫so let's check it out.
‫So as soon as we clicked here on get position,
‫in fact, the user/fetchAddress/pending action
‫was dispatched, and so what this did here
‫was set the status from idle to loading.
‫And so that is actually exactly what we have here,
‫so this one right here,
‫so that's what I was saying earlier.
‫So that dispatching the action
‫would create an action
‫with a type of user/fetchAddress/pending,
‫so exactly what we have here.
‫And so that's what this reducer right here
‫is then responsible for handling,
‫so for updating the state right here.
‫And then as soon as the promise was finished,
‫so as soon as it got fulfilled after all of this work here,
‫so after getting the position and then fetching the address,
‫so after all this,
‫that data was then returned here from the function.
‫And so remember that this then became
‫the payload of the fulfilled state
‫and so this fulfilled state
‫is then handled by this reducer right here.
‫And so this then updated the state here to idle,
‫to the address itself and to the GPS position.
‫And in case the user, for example,
‫did not allow the geolocation to happen,
‫so if we clicked here on block,
‫then this rejected state,
‫so this reducer right here would be caught.
‫So then we would get an error
‫which we could then display in the user interface.
‫Now okay, so our Redux logic here works
‫even though it is, as I keep saying, pretty confusing.
‫But this is basically just a recipe
‫that you will have to follow in case you are interested
‫in creating thanks with Redux Toolkit.
‫So just make sure to maybe review the flow of the data here
‫and how all of this works,
‫and then let's move on to the next video
‫where we will integrate this geoposition logic
‫here into this actual form.