Okay, now let's take a look at what happens when we encounter a server side error that we cannot check
on the client side.
So I'm just going to log out of this user.
And this should take us back to the home page and remove the user or the user menu from the top right.
And let's click on the register button.
And let's try and log in with Bob or Register I should say Bob at test.com.
And I'll give a valid password.
And if we try and register then what's going to happen.
Well nothing.
We haven't got the success.
So we know it failed, but we didn't notify the user that something's not quite right here.
And if we take a look at the console, do we get any errors inside here when we do this.
Well let's take a look.
And we can see that we do have errors in the console.
We've got a 400 bad request.
And we can see that the error is available from somewhere.
Saying that username Bob at test.com is already taken.
And we get that information in the Account API and in the base API.
Actually, we're logging it out there as well, but we don't get it in our component where it would
be useful to show that information to the user, of course.
And let's go and take a look at our code that we're using in the register form.
And for the submit.
We're not doing any error handling in here.
So let's add a try.
Catch inside here and see if we can log the error at least and get it from the component itself.
And I'll just console log the error here.
And if we go back to the browser and we try and repeat that behavior and use Bob at Test.com again with
a valid password that meets the complexity requirements, then we don't see anything coming back to
our register form.
Actually, this is all coming from our account API or our base API, but our console log.
Well, that didn't make it to our form.
That's being caught and handled elsewhere.
So it doesn't make it all the way into our register component.
So let's go back to the account API and where we've got our register where we've got the on query started.
We are catching the error here.
But we also need to throw this back to our component.
So we'll also throw the error.
And if we go back to our browser and just test to make sure that we do have access to the error, because
that will be a requirement for what we need to do with the error.
Then this time we can see that we're still getting nothing from our register component.
Hmm.
Interesting.
So let's go back to our browser again and in our register form.
Then when we use this await register user, we need to use the unwrap functionality so that we do get
access to the response coming back from our query.
And now if we try this one more time, what we should see if I use Bob at test.com and password again,
what we should see is the register form now displaying the error.
And we can see this in the message here.
Email bob at test.com is already taken, etc. etc..
Now we've got something that we can handle inside our register form.
So let's go back to the register form and we can use something that we get from react hook form.
We can also set errors inside our form states as well.
And then we can use them from our form state errors and display the helper message in the field that's
relevant to the error.
So we know that we're getting an error related to the email.
We're also getting it from the username.
But since that's the same property we're using, we're going to ignore that one and just use the one
from the email.
So inside the catch then let's make use of what we get back.
And I'm going to say const API error equals and error.
But we're going to specify as because we saw this coming back in an object with a message property which
was a type of string.
strings.
So let's give it that type and we'll say if API.
Errormessage.
And the type of API Errormessage is equal to a string.
Then we'll do something with that error.
Now we want this to be an array, because this API error is coming back as a string with a comma separated
list of values.
So we'll create a const called error array equals and we'll use API Errormessage dot split.
And we'll use in quotes a comma.
And now that we have this as an array we can use the error array and use for each.
And we'll just specify E for error.
Add the arrow and we'll check to see what kind of error it is.
And we'll check to see if e includes And in quotes, the password.
That's going to be one of the keys of the properties that our API can send back.
We saw that before in postman.
When we received an error response, we saw that we had the password validation inside there.
And then we can use the set error and we can specify the fields.
In this case it's going to be the password field.
And then we can use the message property that we have from our error and set it to E.
And we'll add an else if because we'll also handle the email type of error in here as well.
And because it's an else if I need to specify the E includes and we're going to look for email inside
here.
And then we'll use the set error once again.
And this time we'll target the email property, open curly brackets and we'll specify the message and
E.
So if we go and repeat the behavior that we just looked at, then what we should find is that this functionality
is going to give us our API server side validation inside there.
So let's go take a look and see what happens.
If I once again try and repeat the behavior I looked at before.
So I'll say Bob at test.com with the password and I'll press return.
And what we should find this time is that email Bob at test.com is already taken perfect.
That's the functionality we're looking for.
We should also have the password functionality as well.
But we've got Zod taking care of that kind of validation.
But let's just give it a quick test to make sure that it's doing what we'd expect it to.
So if we go back to our register schema, then let's comment out.
Or just to make it easy, I'll copy this and paste it below, then comment out the password above and
I'll take out the regex stuff.
So we're only going to check to make sure it's a string, and that will pass password validation on
the client side, but of course we'd expect it to fail.
On the server side.
So if I say bob@test.com again and use a weak password like let me in or whatever, whatever's a weak
password and try and click register.
Then this time we get the password must have at least one non-alphanumeric character.
So even though this returns more than one error, we can only actually set one error at a time inside
here.
So they'd get this error back.
Then they'd if they still tried to use a weak password, but with one non-alphanumeric character.
So I use pass.
Let me in one, for instance.
Then we'll probably get a different kind of error back.
Or in this case it's looking for a special character.
So I'll try adding a special character.
Then we should see a different error coming back from here.
So now it tells us we need at least one uppercase, etc. so that functionality is working as well.
But obviously that's not the approach we'll take.
We'll catch that on the client side because we can.
The email, whether or not this is a duplicate email, we cannot tell from the client side that has
to go to the server for the server to say, nope, that email address is already taken.
So great.
That's how we handle the server side validation in our client side.
Now one more task to go to do with identity.
Just now.
We will come back to it as we progress through building this application.
But the one more task that we're going to look at before we move forward is the fact that I can get
to, and I'll need to add something to my basket first to be able to demonstrate this.
It's the fact that I can get to my basket and click checkout and see this page without being logged
in.
We need to take a look at how we can.
I'm going to loosely say add some kind of security into our client side app so that we prevent this
behavior and we redirect them to the login page if they are not logged in.
When they try to get to this area of our application.
And we'll take a look at that next.