Update to .NET 5
What is Blazor ?
Blazor is a free and open-source web framework that enables developers to create web apps using C# and HTML.
To know more about what blazor and all related stuff to it visit official documentation site.
If you have already up and running blazor application you are good to go along. if not, visit official documentation to setup and configure blazor on your machine.
Link of official documentation to get started with Blazor
Get started with Blazor
We often want to show some loading or spinner on UI when our application is making some request to the server, so that users will know that there are some operation going on and need to wait till that operation is complete, We can handle this manually on each time in our code when there is an API call we can show some loading bar but There is a better way to do this and ie let it show the spinner automatically when there is ongoing API call and we can do this my adding our own custom HttpMessageHandler
and show spinner just before sending request and hide that after getting response from the server.
Steps
- Create Spinner Service
- Create Spinner Component
- Create Custom HttpMessageHandler
- Add Spinner Component in MainLayout
- Register Services in startup
Step 1 : Create Spinner Service
Spinner Service class exposes two methods and two event, which will work as a communication channel between other Components (MainLayout
) and Spinner component
public class SpinnerService
{
public event Action OnShow;
public event Action OnHide;
public void Show()
{
OnShow?.Invoke();
}
public void Hide()
{
OnHide?.Invoke();
}
}
Step 2 : Create Spinner Component
Here in this Spinner component , I have some css to show the Spinner on top of other html elements and for Spinner I'm using a Blazor Library called Faso.Blazor.SpinKit
, which we can install from NuGet , It has a different kind of spinner , here I'm using <SpinKitCircle />
. to know more about this spineer visit Github Repo of this this NuGet library.
Here our logic is simple when IsVisible
will be true
it will show the spinner and in the case of false
it will hide.
From our Spinner service when OnShow
event will be fired, ShowSpinner()
method will be called it will make IsVisible
true
same on OnHide
HideSpinner()
method will be called and it will make IsVisible
false
.
@using Faso.Blazor.SpinKit
@inject SpinnerService SpinnerService
<style>
.spinner-container {
display: flex;
flex-direction: column;
position: fixed;
z-index: 999;
top: 50%;
left: 50%;
}
</style>
@if (IsVisible)
{
<div class="spinner-container">
<SpinKitCircle />
</div>
}
@code
{
protected bool IsVisible { get; set; }
protected override void OnInitialized()
{
SpinnerService.OnShow += ShowSpinner;
SpinnerService.OnHide += HideSpinner;
}
public void ShowSpinner()
{
IsVisible = true;
StateHasChanged();
}
public void HideSpinner()
{
IsVisible = false;
StateHasChanged();
}
}
Step 3 : Create Custom HttpMessageHandler
In order to fire OnShow
and OnHide
event each time our application will make request we need to add our own custom HttpMessageHandler
. (i.e. BlazorDisplaySpinnerAutomaticallyHttpMessageHandler
)
Here in our custom HttpMessageHandler
we are injecting SpinnerService
so that we can call Show()
and Hide()
method from custom HttpMessageHandler
that will fire events.
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace BlazorDisplaySpinnerAutomatically
{
public class BlazorDisplaySpinnerAutomaticallyHttpMessageHandler : DelegatingHandler
{
private readonly SpinnerService _spinnerService;
public BlazorDisplaySpinnerAutomaticallyHttpMessageHandler(SpinnerService spinnerService)
{
_spinnerService = spinnerService;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
_spinnerService.Show();
// await Task.Delay(1000);
var response = await base.SendAsync(request, cancellationToken);
_spinnerService.Hide();
return response;
}
}
}
Step 4 : Add Spinner Component in MainLayout
MainLayout
is component which will be rendered for each component so we will add our Spinner
component on our MainLayout
Component.
<Spinner></Spinner>
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<div class="top-row px-4">
<a href="http://blazor.net" target="_blank" class="ml-md-auto">About</a>
</div>
<div class="content px-4">
@Body
</div>
</div>
Step 5 : Register Services
Now our final step is to register our services in startup , here we are registering SpinnerService
, Our Custom HttpMessageHandler
(i.e. BlazorDisplaySpinnerAutomaticallyHttpMessageHandler
) and Also we need to register HttpClient
and pass our custom HttpMessageHandler
as InnerHandler
.
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddScoped<SpinnerService>();
builder.Services.AddScoped<BlazorDisplaySpinnerAutomaticallyHttpMessageHandler>();
builder.Services.AddScoped(s =>
{
var accessTokenHandler = s.GetRequiredService<BlazorDisplaySpinnerAutomaticallyHttpMessageHandler>();
accessTokenHandler.InnerHandler = new HttpClientHandler();
var uriHelper = s.GetRequiredService<NavigationManager>();
return new HttpClient(accessTokenHandler)
{
BaseAddress = new Uri(uriHelper.BaseUri)
};
});
await builder.Build().RunAsync();
}
}
Now run the application , you should see a spinner ,when application will make http calls.
We can show that spinner from other components as well when ever we need to show, we just has to inject SpinnerService
and call Show()
and Hide()
method to show and hide spinner respectively.
Refrence Links
Feel free to comment and suggests changes .
Full source code BlazorDisplaySpinnerAutomatically
Happy Coding!