A Smart Angular Spinner - Scoping on App as well as Component Level
Creating spinner components in Angular is done in almost all web apps. The 1st rule of thumb is to avoid Spinners as much as we can. There are several smart ways to do that. I’ll keep that to a different article. In this article, we will be creating the same old spinner of Angular but with a little trick up its sleeve.
In my frontend development experience with different MNCs, I have seen spinner implementation in few different ways.
- Create a separate Spinner Component and add the selector wherever it has to be used in other components. Set
*ngIfflag to show and hide the spinner inside the component.
- Create a global Spinner Component and keep calling it via service. Generally, it is applied on app level and the entire UI is blocked while the data is loading.
In one of my projects, I came across a spinner component that was applied on the app level. Anytime it was called using spinner service, the entire UI was blocked. It was a straightforward implementation.
So far, so good. But later on, I realized that there were few screens that contained several small components to show data (for example: a Dashboard UI). Hence an app level spinner would restrict the user interaction time until the entire data of all components are loaded. This seems to be a problem to manage because unless the entire data is loaded, the dashboard UI will be blocked.
I decided to explore the possibility of using a Spinner component which can also have scope of both App level as well as Component level. I decided to reuse the same component but with some slight code modification.
Here is what I did:
- Created another
spinner.component.html. I added a template tag
2. I removed
#componentSpinner from visibility using
display:none , so that it is not visible by default. To achieve that, I used
AfterViewInit hook. Once I have the
ElementRef , I saved it inside
3. Now I needed to add this template to our target
Component on which we want to add scoped spinner. Once the loading was completed, I also needed to remove the
#componentSpinner template which I added dynamically.
To handle this, I created:
And, that’s it!
To use it inside a component, we need to add a
#template to the parent div. This would help us get the entire component HTML and add our small spinner code to it.
In our use, we can have an app that has a
DashboardComponent . The Dashboard component may call several APIs and it can also have a few small components such as
UserCountComponent . These components may depend on
DashboardComponent to get some
@Input data or they can independently make API calls inside them.
We can use the
SpinnerComponent scoped to
UserCountComponent by adding
#userTemplate to its parent
And, using the
ElementRef to show spinner on the component level as below:
I have added some intensional delays to mock slow network calls.
I know it may not be a good fit for all use cases, but it extended the feature of existing
SpinnerComponent . If you liked the idea or to improve it further, feel free to drop me a note. For me, it was a fun and unique implementation.
If you liked what you read, please 👏 👏 clap 👏 👏 few times to encourage me 🐼 for writing such articles. Cheers !!