So now that we added storing, fetching, updating and deleting and therefore all the crud functionalities
and we had a look at showing a loading spinner and handling errors,
there are two things missing.
One is that when we actually place an order, that we do send that order to a server too and that we
store the order there as well and not just locally
because right now of course when we order something we see it here but as soon as we reload the app
since we're not storing it on a server, that is lost,
so that's one thing.
The other thing is of course that we only show a loading spinner here
and we also only handle errors here. On the admin screen if something goes wrong,
we get no error, also here if we edit this and we submit this,
we see no loading spinner whilst we're waiting for this to be submitted.
So that's also something we could improve
and that's actually the part I want to start with.
So here on the edit product screen when we dispatch updating or creating, in both cases this of course
takes a while and indeed we get back a promise here because both in the update and create product action,
we're using the Redux Thunk feature of returning an async dispatch function here which therefore returns
a promise which therefore is returned as part of our dispatch function call here.
So therefore we actually get the information, whether we're waiting for the response, whether we got an
error or whether we're done,
we just need to use it
and of course we can use it in a similar way we did before, with use state imported from React and
then by managing the loading and the error state here. Side note, you could of course also work with
a reducer where you merge both states together if you wanted to with the help of the use reducer hook.
Here
however, I'll stick to isLoading and set isLoading and initially of course this is false and also have
the error and set error variables here with use state like this, which initially is undefined
and now we just need to set this as we're dispatching actions or as we're getting errors.
So here when we're about to dispatch this, no matter if we're editing or if we're creating, I want to
set isLoading to true and I also want to set my error here to false or not to false, to null, reset it.
Now once we're done, I want to do something else but for that, we first of all need to wait for dispatching
to be finished.
Now we can therefore turn this into an async function again, just so that I can use to await keyword in
there,
the alternative would be to not turn this in an async function and simply add then and catch thereafter,
that would work as well
but I like to use async await. So now we can await for both dispatches to finish, of course only one
of the two will run because that's an if condition but we can wait for that to finish and therefore
after this if block, we know that will be done dispatching
so here we can set isLoading back to false. So that's the loading state, now to handle errors, we just need
to wrap this with a try catch block and we can actually wrap the entire if block here with try catch,
so let's grab that, move it in here and then catch any potential errors we might be getting here and
now here, I of course want to set my error to the error I'm getting here or to the error message I'm
getting here
Now we're setting the error, we're setting the loading state, of course this has no effect here on this
screen. So to show a loading spinner, we need to import the activity indicator from React Native, activity
indicator from React Native and to show an error,
I also want to throw an alert and for that, you need to make sure that you're importing the alert which
we're already doing. Now as a next step, to handle the loading state, maybe down there before I return
my form, I will check if isLoading is true and if it is, I will return my view
here with the activity indicator in there and there, I'll set the size to large and set the color
to colors and for that, you need to make sure that you import that colors constant primary. So
make sure you have that colors constant imported here, that's required and now I will also use the stylesheet
here to add a new style, this centered style to be precise, here I will add centered and yes we could
therefore also outsource this into a separate wrapping component if you wish to.
There, I'll set flex to one, justify content to center and also align items to center, like this.
Now we can apply this centered style here to the view which I wrap around my activity indicator by
setting the style here to styles.centered.
Now we should be seeing this whilst we're loading and on a side note, we also now shouldn't navigate back
before we're done.
So if I add or if I remove that exclamation mark and then leave that input so that this is submitted
and I click save,
you saw the loading spinner and we only navigate back after this is done.
Now Firebase is super fast but still, that is what happened.
Now to simulate an error, I'll go to the products actions and there in update product down here, I will
remove that s here again to force an error and I will also add something else,
I will now store the response here in a constant because now I actually do care,
I want to make sure that if the response is not okay,
so if we have a 400 or 500 status code, I also throw a new error where I say something went wrong or where
you do whatever error handling you want to do, so that we also throw an error in that case. By the way
I'll do the same for deleting before we test this forced error which I implemented.
So here for deleting, I also want to check this and for that of course here,
I also need to get my response by awaiting the fetching here. Okay with that,
let's see if that forced error for updating due to dismissing s here,
if that has an effect. If I now go back here to admin, I start adding this, I add an exclamation mark and
click this,
now what you'll see is that the update is simply dismissed, so we don't see the exclamation mark here
but we also get no error message which makes sense because I have no logic to do that.
Now how can we handle this?
As I said, I want to throw an alert and therefore
I will use use effect, so that use effect hook which React offers which we find here,
I want to use that and I can simply implement that here
after initializing the reducer let's say, exact position doesn't matter too much. Use effect here should
rerun whenever error changes,
so if we set this to be an error to not be an error, then here I check if error is true-ish,
so if we have an error and if we do have this, then I can throw an alert,
an error occurred.
I want to output my error here and that should be the error message because that's what I'm setting
here,
I'm setting my error to the message so that should be a string which I can output and then I'll
add a button where I say OK which simply dismisses this. Now also important, if we get an error,
I don't want to navigate away. So to avoid that this happens, I want to make sure that here, this props,
this navigation here actually only is performed if we don't end up in this catch block.
So basically here after the if else block but still in the try block, there I want to navigate away.
So now let's give this another try,
let's go back here,
edit this, add an exclamation mark, click somewhere else, click save
and now I get my error message here and I stay on this page and it's also reset. I can add this again,
click here and it's gone.
On the other hand if we now fix that error here in the actions by readding that s here and we now go
back and have another look at this, if
I edit this, add my exclamation mark, click somewhere else and click save,
now that all works as it should.
So now this really works and now this behaves in the way it should behave.
Now you can of course also add a loading spinner and an error handler here to the user product screen
if you want to.
So if you delete this which I won't do here but if you would delete this, you would currently not get
a spinner, a loading spinner,
you also won't get an error if it fails. To save some time, I'll not implement this here but you could
implement it in basically the exact same way we did before if you wanted to.
So that's something you can definitely also do.