In the previous exercise,
we updated our Angular applications services to use promises,
and also updating the components to
deal with the promises that are returned by the services.
In this exercise, which is an extension to the previous exercise,
we're going to simulate a time delay for the promise to resolve.
In the previous exercise,
the promises were resolving immediately.
But in real life,
when you request data from a service and the service delivers a promise,
the service, in turn,
needs to go and fetch the data from a back-end server,
and this will take time.
So, for the promise to resolve,
there will be a certain amount of time delay.
Now, how do we deal with this time delay on our component side?
How do we keep the user informed about the fact that there is
a time delay involved before the data can be fetched and shown to the user?
How do we deal with the delay itself?
Now, in this exercise,
I'm going to simulate the time delay by using a JavaScript method within my services,
and then also update the components to be able to show a message to the user using
the Angular material progress spinner component to show a spinning disk in
the template view to keep the user informed about
the fact that the data is being fetched from the server,
and we'll render in the view as soon as the data becomes
available to the component when the promise resolves.
Let's see how we can do that in this exercise.
Again, going back to my service,
here I have the dish service open here.
Instead of having the promise resolved immediately,
we are now going to deliver a promise and then let
the promise resolve after a short period of time.
So, to do that, this promise resolve will not work
anymore as shown here so I'm going to delete that.
Instead, when my method is called,
the method will return a promise by creating a new promise.
You recall that when you created the new promise,
inside the promise you would have the function
with resolve and reject as the two parameters.
Now, I'm go to only use the resolve part of it.
So, I will implement the function inside the promise just using an arrow function here.
So, I will say resolve,
and I will simulate a short delay for this resolution to take place.
Let me write a comment.
Simulate server latency with two-second delay.
So, how do we simulate this?
So, we use the setTimeout method
that is available in JavaScript.
So, for the setTimeout method,
again, I will implement an arrow function,
the setTimeout method doesn't have any parameters that we need there.
So, when this setTimeout executes,
then it will resolve delivering the DISHES.
So, let me cut this DISHES and then paste it into the DISHES.
So, you see that this result is now returning the result here,
and this result will be returned after two seconds delay here.
With this update, our promise now will resolve after two seconds.
So, the setTimeout method available in JavaScript simulates a short delay.
So, as you can see,
it simulates the short delay and takes a callback in here.
This callback as you can see,
I have implemented it as an arrow function here.
So, no parameters and then when this resolves,
it is going to resolve returning the DISHES and the delay for that is two seconds.
So, this part is the function,
and this is the time delay that we have here.
So, now, my promise will resolve after a two-second delay.
Similarly, let's update the remaining two methods here.
So, to do that,
I'm just going to copy
that part and then simply paste that in there,
and you would notice that that
will and I need to say 2000.
So, that completes the setTimeout method there.
Now, we will have
the closing parenthesis followed.
Similarly, let me update the last method also.
So, you see that it resolves the DISHES,
and then after two seconds delay,
and close the method to there.
That's it. So, now my dish service is
updated to resolve all the promises after two seconds delay.
Now, similarly, update the leader service and
the promotion service using the same pattern as I have shown you here.
The second part of the question is to somehow keep the user informed about
the fact that there is a time delay involved in obtaining the results,
and so the view will update as soon as the results are obtained.
You have seen this kind of behavior in many applications,
including mobile applications where you would have a spinner shown on the screen to keep
the user informed about the fact that something is being loaded from behind
the scenes and when the results become available,
the view will be updated.
So, we're going to use a similar approach within our components.
To help us with this,
we will use the progress spinner component from Angular Material.
So, to use the progress spinner component,
let's first go to the app
module.ts file and then import the progress spinner module in there.
So, going to app module.ts.
We will first go up here to import
the MatProgressSpinnerModule from angular/material/progress-spinner.
Once we have imported this into the file,
then we will go into the ng module decorator into the imports,
and then add in the MatProgressSpinnerModule into that.
Once we complete this,
then we can update the components to make use of the progress spinner.
So here, I will show you an example by
illustrating how we can update the menu component to show this information.
So, go in to the menu components layout file.
Here, we see that we are showing the menu using the grid list here.
So, what we will do is, for this div,
I'm going to use the ngIf directive and say that this should be displayed.
The menu should be displayed only when dishes is not null.
So initially, in your components tab script file,
you will see that when you go to the components tab script file you will see that
your dishes is currently just an undefined object here,
and that dishes will be assigned to the dishes value only when the problems resolves.
So, until that point,
the dishes will be an undefined value.
So, we can take advantage of that fact,
and then re-design our template such that,
we would say show this div only if the dishes is not an undefined or not a null object.
When it is unknown,
then I will use a second div here with the hidden attribute associated with it.
So, you've seen hidden being used before.
So, I'm going to use that to define the stem.
So, what this means is that if dishes is not null,
then this div will be hidden.
If dishes is null,
then this div will be shown.
So, now you see that you have two divs here.
The first one will be shown if dishes is not null dish array.
Otherwise, the second part will be shown.
So, with this little change to my template,
I'm able to hide the menu until the point that the dishes array becomes available to me,
and when the dishes array becomes available,
then I will show the menu.
Until that point, I'm going to show a mat-spinner.
Which is undeterminate progress spinner
that is available as an angular material component.
So, this will show as a rotating circle in my view,
for this menu component until the point that the results are obtained,
when the problems resolves.
In addition, I will also use h4, and within the h4,
I will say loading, please wait.
So, what happens is that when the dishes is not yet resolved,
the spinner and this message will be shown on the screen.
The moment the dishes becomes available when the promised results,
then the menu will be shown on the screen.
Now, we will do similar updates about component,
the home component, and the dish detail component also.
Correspondingly, we will update the leader service,
and the promotion service also to simulate the time delay.
So, using the pattern that I've just illustrated to you,
go ahead and update the services and also the corresponding templates,
and we'll see the result after we finish the update.
After you complete the updates of all the services and
the corresponding templates for the components,
let me quickly run you through the updated files here.
So, this is leader service.
So, you can see that in the leader service,
I have updated the getLeaders to use the setTimeout exactly like we did with the dishes,
and the getLeader and the getFeaturedLeader also.
Similarly, in the promotion service,
we have updated the getPromotions getPromotion id and the getFeaturedPromotion also.
So, the three services are now updated
to cause a time delay before they return the result.
Now, in terms of the templates,
we have already updated the menu.component template.
Let's look at the home.components templates.
So, within the home.component,
you realize that when we designed the home.component,
we had already configured the cards with the star ngIf dish.
So, all that we need to do is,
down below here we add a div with
the hidden and dish here but the spinner just like we did with the menu.component.
Similarly, for the promotion the mat-card already has the ngIf in place,
so we just need to add this additional div here with the hidden promotion there,
and also for the leader here down below.
Similarly, going to the dish detail component.
In the dish detail component,
we already had the list with the ngIf dish for the comments.
Also, the ngIf dish for the card that displays the details of the dish.
So, all that we need to do is add in this new div with the hidden dish here,
and the div spinner in place.
Similarly, in the about component,
when you go into the about component,
you would see that we had the corporate leaders here,
and we already had the list with the star ngIf with leaders.
So, all that we need to do is add in the div with
hidden and leaders here with a spinner in place. That's it.
Our application is now updated.
Let's take a look at the updated application in the browser next.
Going to the browser,
you'll see that when you try to load in the home component,
there is a short period of time when you see the spinner on
the screen before the cards get loaded.
Similarly, when you go to the menu.component,
you would see the spinner on the left side for
two seconds before the actual menu gets updated,
and when you go to an individual dish also you see that
the spinner on the screen before the details of the dish are rendered,
and in the about component also similarly, you will see that,
you will have the spinning circle there before the leader's information is updated.
Anytime we move to any of these,
you would see a similar short delay before the inflammation is updated on the screen.
So, with this you see how you can deal with delay in obtaining the results,
or delay in the promise resolving from the service side within your component
and keep the user informed about the fact that there is
a short delay before the screen gets updated.
This completes this exercise.
In this exercise, we saw how we can simulate a short delay with our promises.
Getting resolved from the services,
and we also saw how to keep the user informed by using the MD spinner
angular material components to show on the screen for
the duration when the results are not yet available,
that is for the duration until the promise gets resolved.
This completes this exercise.
This is a good time for you to do a git commit with the message promise Part two.