[MUSIC]
Communication between client and server is never a done deal.
To paraphrase a famous proverb,
there is many a quiver between the client and the server.
So how do we deal with errors when they arise,
when we are communicating between the client and the server?
Let's talk about that in this exercise.
When the server generates a response, or the HTTP client,
while communicating with the server, encounters an error and then generates
an error response, this is delivered in the form of HTTP error response.
Now, this response, we want to be able to process it and
then turn that into a response message string, which
can be delivered to the client so that the client can display this on the screen.
So to enable us to do that,
we will create a new service named process HTTP message in this, this is folder.
So to do that, at the prompt type ng,
g service services/ProcessHTTPMsg,
and generate the ProcessHTTPMsg service.
Now, once the service is generated, we will then go ahead and
add it into the app module.
And then we'll add in a method to the ProcessHTTPMsg service.
Now that we have created the ProcessHTTPMsg service,
let's go ahead and then add that into the app.module.ts file.
So going to the app.module.ts file,
let me import the ProcessHTTPMsg service,
From './services/process-httpmsg.service'.
So once that is imported, then we will be able to use that in our application.
So let's go ahead and add that into our providers.
So going into our providers,
let me add in the ProcessHTTPMsgService into the providers.
The first thing that we will do is include a new method into
the ProcessHTTPMsgService called handle errors,
which will take care of handling errors when they arise.
And then we will make use of them in the services where we access the server.
To get started, let's first import,
throwError from, rxjs,
and this helps us to throw in error whenever that arises.
And then we import HttpErrorResponse from,
angular/common/http.
Then we will start designing handleError method, and
this takes, as a parameter, an error which could be a response,
which is an error response from the server,
or any other reason that the error arises.
So within this handleError method, what are we supposed to do?
Let's try to construct a message that summarizes what the error is all about.
So we will include a new string variable here.
If error.error is an instance
of ErrorEvent, so if this is an error event that occurs,
then the error.error.message will contain information.
So we'll set the error message to
error.error.message.
If that is not the case, then that means that this is coming from the server side,
and so in that case, the error message is constructed by saying equal to backquotes,
note the backquotes here, and then ${error.status}.
So we are extracting the status information from there.
And then,- error.statusText,
if the statusText exists, or
that'll be an empty string there.
And then we will also include the error.error itself,
the complete error object itself, right there in the string.
And then use that as our error message.
Now, once we have the error message,
then we will be able to use the throwError to
return an error observable to our application.
So what this means is this is throwing an error at this point,
with the error message included there.
So this error message string is constructed based upon the information
that we obtain here, either because the server side responded with an error or
the error could be from other reasons.
So in either case, we will construct an error message and then return it.
Now, where do we make use of this handle error?
Now, within our services, for example the dishservice.ts file,
we saw that earlier when we said this HTTP get, and then we just said map,
and then assumed that the response is always a positive response.
But suppose their response is not positive, and
then it returns an error, then we need to catch that error.
To help us with this, we import the catchError operator from rxjs,
and then we also import the ProcessHTTPMsgService
that we just created earlier into
our dish service so that we can use the handle error method from there.
So we import this from the ./process-httpmsg.service.
And then, going down to the constructor,
we now inject the process HTTP message service
into the constructor, along with the HTTP client.
So that we can make use of this service,
especially the handle error method of the service to handle the errors
which are returned by our HTTP client there.
Now, once we have configured the constructor,
then to handle error in the getDishes method for
example, we will pipe to catchErrors method.
And then call the handleError method after
this.processHTTPMsgService within the catchError method.
So this way When the HTTP client returns a error then this will be processed and
the appropriate error message will be extracted.
And then it will end up throwing the error through
the handleError method at that point.
Similarly, let's do the same to the getDish and
the getFeatureDish methods also.
Now, when it comes to the getDish ids method,
since the getDish ids method is making use of the getDishes method,.
So we don't need to explicitly call the handleError because if any error arises
the getDishes method will have already converted that error into an error string.
So we just need to catch the error and then return the error from getDish Ids.
Normally, we wouldn't even come up to this point if an error arises, because
the getDishes method would have handled the error appropriately at that point.
So once we have configured the dish service appropriately,
then we will be able to then make use of the catchError
method to deal with the errors that arise.
Now that we have updated our service to be able to deal with errors.
How do we handle this within our component themselves?
So within a component, so for example, when we go to the menu component.
What we realize is that when we do the subscribe,
we were expecting the dishes to be delivered to us.
Now, it is possible that the instruct of the dishes,
the error will be delivered by the observable throw and
then that results in the error message being available to us.
So, to deal with that situation, I will introduce a new
variable called errMess in the menu component which is of type string.
And then the subscribe method itself provides a way of handling errors.
So the subscribe method, right now we have only specified one function here.
We can also specify a second function which will
be called when the error results.
So in this case, I can supply a second error function saying,
errMess, which is the value returned in
when the observable throw is done by the dishService.
So in this case, I would say this.errMess = errMess, and that's it.
So here what happens is that when the observable
is returned by the dishService is a Value,
then that would be handled by the first part.
If the observable is returned with the observable throw,
then this function will be executed.
And in this function, we are taking the error message and
then capturing that error message into this errMess string that we have here.
So now we have the error message available to us, so
we can display this error message on the view of this menu component.
So how do we display this in the menu components view?
So going to menu components template file, here we see that if dishes is not null,
then we are displaying the menu with all the dishes.
If dishes is null then this spinner is being displayed there.
Now, we will add in one more here,
even if the errMess that we have,
the variable, is not null, then also
the spinner should be hidden and then,
finally, add in one more div with an ngIf.
So what this does is that this last dive will be displayed in
case there is an errors, and the error message.
ErrMess string is set up to the error message.
So in that case, we'll just simply say h2 error,
and then I'm just going to display that string as,
A string within the view there, that's it.
You can do a more elaborate way of displaying the error message if you so
wish to.
But all that I'm going to do is if there is an error,
I will simply show error on the screen and then display an errMess.
You can even style it by changing the color to red and
so on, but I'll just leave it like that there.
So, with this, we will end up displaying the error message in the view here.
The same procedure can also be used with the dish component and
also the home component where we are accessing the dish service.
So going to the dish component, am going to do exactly the same thing,
so within the dish component I will include the, ErrMess here.
And then right here within the subscribe,
this is where we are receiving the dish value.
So the first part,
what we have already included will be called if the observable returns a value.
But should it not return a value, then we need to deal with the error message.
And we'll use exactly the same
error message function that we have defined earlier in the menu component.
So, we will say that this.errMess
= Ermess here.
That's it, so my dish component is now updated.
So I need to update the dish component's template file.
So going to the template file,
we see that we are going to be displaying the dish if dish is not null.
And then down below here, we are handling the situation
where we'll show the spinner if the dish is null.
So let me add in also, if the error message is not null then I should
be displaying error message rather than the dish here, right?
So, let me go ahead and
copy the code from the menu component.
I'm going to use exactly the same code for
the dish detail components template file also.
So, right there.
Let me go ahead and insert that code here.
So we see that if errMess is not null,
then this error will be displayed in the view there.
Now same thing,
going to the home component we need to go through the same procedure.
Now within the home component, of course, we have dish, promotion, and leader.
So I'm going to define separate, Strings for
each one of them because the error could arise from any one of the three.
Right now we're only dealing with dish being fetched from the server side.
The remaining two I will expect you to do that as part of the, Final assignment.
So we'll, I'll say dish errmess string and then go down into the code here.
And in the code here,
we'll simply say errmess.
This dish errmess = any
errmess, that's it.
And similarly, update the home components template files.
And going to the home components template file,
we see that we have the dish bin displayed there,
so now for this one I should say or dish errMess.
And then, down below here, I will include the code
that I have copied from the menu component, and
then I update it to dish ErrMess here.
And also, update this to dishErrMess here, that's it.
Let's save the changes.
Going to the browser, you see that everything works just like before.
The home, the menu component and also the dish detail component without any problem.
Now the question is, how do we cause errors?
To cause errors, one possible way that we can deal with the issue is we go and
seek a nonexistent information from the server.
Let me go to the dish service and then cause
my first problem in the dishService here.
So for the featured dish instead of dishes, let me make a mistake and
say dishees and then save the change.
Obviously that means that this url doesn't exist.
So, what will happen if it access the server?
Going to the browser when we now scroll,
you see that the dish is not being displayed here.
It says here Error 404 Not Found.
This is because we are trying to access the dish information at
the URL dishees which doesn't exist on the server side.
So you see how the error message is being displayed here.
Of course, you can be a bit more fancy and do more work around this and
then display the error message in a more meaningful way.
But the basic principle is highlighted here saying that you
can show an error message if something is not properly executed
when you are trying to access information from your server side.
Of course, so this is an artificially created error in my application.
To cause yet another kind of error, I have gone to my terminal window and
then shut down the server to see what my Angular application will do in this case.
So after shutting down the server,
let's see what the home component will display in its view.
So going to the home component, we now see that because my Angular
application is not able to access the server, it has caused an error again.
And then it shows this string there to indicate that some error has occurred.
Of course, this is a cryptic string,
doesn't convey anything meaningful about what the source of the error is.
But that's all that we could get trying to access the server in this application.
Same thing, if I go to the menu, you will see the same kind of thing being
displayed, because the server is not available, and so
the dish information cannot be fetched from the server.
With this we complete this exercise.
In this exercise, we have learned how to deal with
errors that arise during client server communication in our Angular application.
This is a good time for you to do a git commit with the message http part two.
[MUSIC]