In the first part of this series on load spinners, we implemented a simple load spinner using the progress spinner component from Angular Material. That can be fine on its own, but depending on how quickly the conditions are met in order to remove the spinner from view, it can lead to a poor user experience. The most common case would be when you are displaying the spinner while waiting for a response from a server. If the server gets that response back to you in a few milleseconds, you could see the spinner flash for a very brief time and then disappear. That can be jarring and can impact how positively your users perceive your application. It would be nice to force the spinner to wait a bit before it appears, and if the response time exceeds a certain threshold, make it appear.
This is a similar problem to what we had in the last article but with a small change. We want the app to display the spinner while it makes the API call, but only after a brief delay which we can set as a parameter.
You may delay, but time will not. -Benjamin Franklin
Let’s look at a simple example that demonstrates one way to resolve this problem. Once again, the code for this example can be obtained here but you will want to switch to the ‘with-component’ branch.
The basis for our approach to this problem is to understand that the bare Angular Material progress indicator cannot solve this for us because it doesn’t have a parameter for delaying its appearance. So we can wrap it up in a component that does, which we will create. This component will include a timeout that will set the property to show the component to true upon completion. However, if the component is destroyed before the timeout completes, it will clear that timeout upon destruction.
There are really only two files we need to focus on for the purpose of this example. The first is the movie.component.html which has swapped out the bare Angular Material progress indicator for our new app-spinner component.
We don’t even need to touch the movie.component.ts file, because there’s nothing to change there. It just needs to keep calling the API and indicate when the response has arrived. We’re still using the asynchronous
loading$ property to pass that state to the progress indicator.
As you can see, the app spinner component does what we described above. It incorporates a
delay parameter that is used to determine the timeout period, which wraps the casting of the
show property. Within
onDestroy it clears the timeout if it still exists, which will only be the case if the API response was faster than 250 ms, or whatever number we used to override the default value for
That’s all there is too it. This can be a nice pattern to use for situations where you need a progress indicator and you can’t be sure whatever you’re waiting for will take long enough to warrant showing the spinner.