Okay.
Now let's take a look at the validation error.
And if we just double check the format of what we get back from react query for this, what we've got
is a data object an errors object.
And then we've got our problem objects.
What I'd really like to happen here is I'd just like these strings formatted as a simple array, so
that we can return that to our component and let our component handle the validation errors, because
that will be unique to the component on each occasion.
So validation errors is something that we will need to handle on a component by component basis.
But what I would like to do is ensure that we just send back a simple array of the different problem
messages.
So that's what we'll aim for in this.
And let's go back to the base API query.
And let's take a look at what we're doing for this part of the code where we've got our else if statement.
And we have that errors object in response data.
Now instead of a test for this one we will throw the error back to the component.
And so that we can get the values from the objects.
We can use the object values method.
So I'm going to say objects dot values.
And then I can pass in response data dot errors.
And we want to flatten this array and make sure it's a single array.
So we can use the flat function.
And then we can use the join function.
And in quotes we can specify comma space.
And if we go and take a look at the effect of that because in our about page, let's just go back and
make sure we're doing what I think we're doing inside here.
When we trigger the validation error, we're catching the error.
And we're logging out to the console now because we're throwing the error from the base API, then we
should be able to catch this now inside here and see the outputs in our console.
So let's go take a look.
And if I click on Test Validation error then what we get is the error message.
Sick and not quite what I'm looking for there, actually, because this is coming from page bundle and
it's not actually coming from our component.
So that's not quite the desired result we're looking for here.
But we need to do something extra when it comes to RTK query in handling this type of response.
So I'll just go back to the component and where we've got the trigger validation error.
Then we can use unwrap inside here which will effectively give us the response rather than this page
bundle thing that we saw just there.
And if I go back and I test the validation error again, this time we get a better response.
We can see the message.
And this is the first error.
This is the second error.
So it's still not quite the format we're looking for because now we've just got a string with our two
messages concatenated together.
But what I really want is an array that we can loop over in our component so that we can display the
errors more easily.
So we've got a bit more work to do.
So let's go back to our component here.
And I'm going to create a helper function.
And I'll say const get validation error.
And I'll also combine this with the trigger function as well.
So I'll make it async and add the opening parentheses.
Add the arrow open curly brackets and then we'll use a try catch block inside here.
And inside the try we'll specify await and then trigger Validation error.
And we'll use the unwrap function on this as well.
And then we catch our error.
And I'll just use any filler short term and say console.log.
And then instead of using the catch functionality in here for the onclick we'll just say get validation
error to execute and call the function.
And this doesn't really do anything great for us at the moment.
If I just refresh the page and test the validation error, then we're back to where we were before,
but now we've just extracted it into its own function.
So how do we get this into an array then?
Well, let's go take a look.
So I'll just do this inside here for the time being.
And I'll say const error array equals.
And we need to use error.message dot split.
And then open quotes add comma space.
And that should give us the array of messages.
So I'll specify error array.
And if we go back and take a look at the console again and click the test validation error.
Then this time we've got what we're looking for.
We've got the array of error messages.
And that's something that we'll be able to loop over.
But we've got TypeScript warnings and we don't want any warnings in our code.
And sure, we could go to our configuration and allow ourselves to use the any type without TypeScript
spitting out a warning about this.
But I don't want to do that in a training course.
And even if it is a tiny bit awkward to give this the correct type, then that's what I'll endeavour
to do so we can use unknown instead.
We don't get a warning when we use unknown, but what we do get is an error or a warning telling us
that error is type of type, unknown and unknown doesn't have a message property.
So we could once again use a type guard for this to make sure there is a property and then use that
on here.
But we're going to see some complications here.
So this one's going to get a tiny bit complex.
So we're going to see if we've got an error first of all.
And we're going to check to make sure that the type of is equal to object.
And there's a message property in error.
And because we've got a const here we're going to need to open up curly brackets.
And I'll put our const and our console.log inside the curly brackets there.
But we've still got another problem here.
And it tells us that error message is of type unknown or the message is of type unknown.
So we also need to specify the type for the message as well.
And this is where unfortunately it gets a little bit more complicated.
So after the in error we'll need to also check the message.
And we'll specify a double ampersand and type of and in parentheses we'll check the error as.
And then we need to specify message colon and unknown because that's what it is.
And then we can specify after the parentheses we can access the message.
And we can say that this is equal to a string.
And then in order to make the TypeScript warning to go away, we'll need to put the error itself inside
parentheses and say error as an in curly brackets message colon string.
And then we can use the message split without any TypeScript warnings.
Now, I appreciate this is horrendously complex for what feels like very simple functionality, but
what we're really doing here is we're using type guards to narrow down what it is we're working with,
so that TypeScript can understand this and take away the warnings.
And if we take a look, I'll just move this down.
And if we take a look at what we're really doing here, we're checking to make sure we've got an error.
Great.
We have.
Then we're making sure that the type of error is an object, and there's a message property inside the
error object.
And then we're checking that message property.
So if the type of error and then we use the as keyword.
And the message is unknown at this point because that is what it is, then we're effectively setting
the message to be equal a type of string.
Once we have the message as a type of string, which is what it is, if we hover over this, then we
can use a string function of split which allows us to split this string and effectively convert it into
an array.
And then once we have that, we can use the console log array.
So TypeScript and probably this is why it sometimes gets a bit of a bad reputation is sometimes it can
be a bit complex to use type guards and narrow down what it is that TypeScript is working with at that
point.
It's particularly tricky when it comes to error handling, because we do not know, or TypeScript has
no way of knowing what the type is that's going to be coming back from an API server.
So we end up doing all of this type checking before we can get to the point where we can actually use
it.
So the goal of this was really to convert this into an array, which we now have.
And inside this component, because typically we would use validation messages inside the component
itself.
So we'll use local states and I'll specify const in square brackets I'll have validation errors As the
property and sets validation errors as the function and say equals use states, and we'll give it an
initial value of an empty array, and we'll give it a type of string array.
And then inside our get validation error method, instead of the console dot log, we can set the validation
errors and set it to the error array that we've created.
And we shouldn't see any errors there.
And then we can go ahead and use our validation errors.
So down in our component just underneath the button group let's use the validation errors.
And we're going to check to make sure it's length is greater than zero.
Because we're initializing this with an empty array at the double ampersand open parentheses.
And then we're going to use an alert that we get from Mui material.
We'll give it a severity of error because we're displaying validation errors.
We'll give it an alert title, and we'll just specify validation errors as the alert title.
And then we'll use a list that we get from UI material.
And inside the list we're going to loop over our validation errors.
So we'll say validation errors dot map.
We'll have the error which is just a string.
At this point.
Use the arrow open parentheses and then we'll have a list item.
And we'll give it a key equal to error.
And we'll specify inside the list item we'll use the error.
And what we should have now is when we do have a validation error then this should be displayed inside
our component.
When it comes to using this again I'll move out this functionality into its own helper function.
So we don't use this every time.
We've got a simpler way of using it, but I won't do that just yet.
I'll come back to that later.
So when we use something for the second time and it's a bit of a chunky bit of code, then that's a
good opportunity to move it into a helper function.
But I won't do that right now.
We'll just make sure we've got the functionality working.
So inside here let's just refresh the page, make sure there's no actual errors from what we've done.
And if I click on the test validation error button what we should get is our validation errors displayed
inside the component where we're using them.
So that's the complex one or the more complex one out of the way.
And it's not complex in the case of what we've done here, it's the TypeScript stuff that makes this
more complex than you would possibly think it was going to be.
But anyway, that's done now, and we can come back to this and use this in any component we wish to.
And we'll create a helper function for some of the boilerplate type code that we've created a bit later
on.
What we'll take a look at next is adding a component so that we can display server side errors in our
client browser, and we'll take a look at that next.