Table of Contents
Introduction
In this post, we will see how to create a Blazor loading spinner component when there is a delay in fetching. Creating a loading spinner component in Blazor is quite simple.
Take a look at the finished Blazor loading spinner in a Blazor Web App.
Creating a Loading Solution and adding a Razor class library project
- Open Visual Studio 2022 and click the Create a new project button.
- Select the Razor Class library project and click the Next button.
- Enter Dnc.Common.Razor in the Project name textbox and Loading in the Solution name and click the Next button.
- Select .NET 8.0 as the version of the Framework to use and click the Create button.

Creating the DncWrapper component
A wrapper component is a component that encapsulates other components or elements within itself, There are many uses for this encapsulation, Including extra features, altering behavior, or simply altering the appearance of the encased content.
We can add more functionality to the wrapper component as we did in the next post creating a blazor toast component using c# only, html and css.
The DncWrapper
component will be responsible for maintaining the functionality of the blazor loading spinner.
- Right-click the
CS.Common.Razor
project and add a new project folder called Wrapper - Right-click the Wrapper folder and add a class that derives from
ComponentBase
namedDncWrapperComponent
namespace Dnc.Common.Razor.Wrapper
{
public class DncWrapperComponent:ComponentBase
{
[Parameter]
public RenderFragment ChildContent { get; set; }
public bool Loading { get; private set; }
private CancellationTokenSource cancellationTokenSource;
public async Task<T> AwaitTask<T>(Task<T> task)
{
SetLoading(true);
try
{
cancellationTokenSource = new CancellationTokenSource();
return await task.WaitAsync(cancellationTokenSource.Token);
}
catch (TaskCanceledException e)
{
e.Data.Add("CanceledTask", "true");
throw;
}
finally
{
SetLoading(false);
cancellationTokenSource = null;
}
}
public void SetLoading(bool loadoing)
{
Loading = loadoing;
StateHasChanged();
}
}
}
There are two methods in DncWrapperComponent
that are publicly accessible.
The SetLoading
method is responsible for setting the Loading
property in the component and calling the StateHasChanged
method to notify the component that its state has changed , which causes the component to be re-rendered.
The AwaitTask<T>(Task<T> task)
method receives a Task
object as a parameter, sets the Loading
property to true
by calling the SetLoading
method, and calls the WaitAsync
method on the task object, which either completes with the result of the task it’s invoked on or throws a TaskCancelledException
if the task is cancelled when the cancellation token is set to cancelled state.
Creating the DncWrapper Razor markup
Right-click the Wrapper folder and add a Razor component that derives from DncWrapperComponent
class named DncWrapperComponent
@inherits DncWrapperComponent
<div class="dnc-wrapper">
<div class="loading @(Loading ? "show" : "")">
@if (Loading)
{
<div class="dnc-wrapper-spin fa-x3 d-flex justify-content-center align-items-center">
<div>
<i class="fas fa-circle-notch fa-spin"></i>
<div>
<span>Loading...</span>
</div>
</div>
</div>
}
</div>
<CascadingValue Value="this">
@ChildContent
</CascadingValue>
</div>
The spinner is only rendered if Loading
property is true
by using an @if
directive, otherwise the content is rendered, and the DncWrapperComponent
component instance is passed as a complex type to all descendent components.
Descendant components can then perform actions against the instance using its methods and bind to its properties.
We use fontawesome’s spinner classes to display a loading spinner with custom CSS classes as shown in the next section.
Also read https://dotnetcoder.com/dependency-injection-in-asp-net-core/
Creating the styles
Right-click the Wrapper folder and add a style sheets file named DncWrapper.razor.css
.dnc-wrapper {
position: relative;
min-height: 50rem;
}
.dnc-wrapper > div.loading {
z-index: 1001;
width: 100%;
height: 0px;
position: absolute;
opacity: 0;
transition: opacity 0.5s;
text-align: center;
pointer-events: none;
}
.dnc-wrapper > div.show {
height: 100%;
opacity: 1;
backdrop-filter: blur(5px);
width: 100%;
background-color: rgba(255,255,255, 0.7);
}
.dnc-wrapper-spin {
height: 100%;
max-height: 60vh;
margin-top: -1rem;
}
.dnc-wrapper-spin div span {
padding-left: 0.8rem;
font-size: 1rem;
letter-spacing: 0.1rem;
color: #666 !important;
}
div.loading .fa-spin {
font-size: 5rem !important;
color: #b1b1b1 !important;
}
Creating a Blazor Web App
1. Right-click the Loading solution and select the Add, New Project option from the menu.
2. Select the Blazor Web App project template and click the Next button.
3. Name the project Dnc.Loading.WebApp
and click the Next button.
4. Select .NET 8.0 as the version of the Framework and Server in the Interactive render mode and click the Create button .
5. Right-click the Dnc.Loading.WebApp
project and select the Add, Project Reference option from the menu and check the Dnc.Common.Razor
checkbox and click the OK button.
6. Update the _Imports.razor
file
@using Dnc.Common.Razor.Wrapper
7. Include the bootstrap and fontawesome links in the App.razor
file, as shown below.
<!DOCTYPE html>
<html lang="en">
<head>
// Removed code for brevity
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/fontawesome.min.css"/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/js/all.min.js"></script>
<HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender:false)" />
</head>
<body>
<Routes @rendermode="new InteractiveServerRenderMode(prerender:false)" />
<script src="_framework/blazor.web.js"></script>
</body>
</html>
Notice that we disabled the pre-render mode, so the OnInitializedAsync
will only be triggered once.
Using the DncWrapper that holds the Blazor loading spinner in the Blazor Web App
In this section we will learn how to use our custom Blazor loading spinner in the Blazor application.
1. Encapsulate the MainLayout.razor
component with the DncWrapper
component, which holds the Blazor loading spinner functionalities, and an instance of it is passed to all descendent components to perform actions against the instance using its methods .
@inherits LayoutComponentBase
<DncWrapper>
<div class="container">
@Body
</div>
</DncWrapper>
// Removed code for brevity
2.Right-click the Pages folder and add a class that derives from ComponentBase
named EmployeesComponent
namespace Dnc.Loading.WebApp.Components.Pages
{
public class EmployeesComponent : ComponentBase
{
[CascadingParameter] protected
DncWrapper DncWrapper { get; set; }
protected List<Employee> Employees = null;
protected override async Task OnInitializedAsync()
{
Employees = await DncWrapper.AwaitTask(GetEmployees());
}
private async Task<List<Employee>> GetEmployees()
{
await Task.Delay(3000);
var json = File.ReadAllText(@"./Data/employees.json");
return JsonSerializer.Deserialize<List<Employee>>(json, options: new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
}
}
public partial class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
public string Designation { get; set; }
public string Department { get; set; }
}
}
3.Run the application, and navigate to the /employees
page, and observe the Blazor loading spinner that will be displayed for three seconds due to a delay in fetching data.

After completing the task the Blazor loading spinner disappears, and the data is displayed on the page.

Conclusion
In this post we created a Blazor loading spinner that can be used in your different projects. We started by creating a wrapper component that encapsulates the Body
property in the MainLayout
component, which provides the Blazor loading spinner functionality to the encased content.
The code for the Blazor loading spinner can be found Here.
Also read https://dotnetcoder.com/azure-service-bus-queue-trigger-azure-function/
Enjoy This Blog?
Discover more from Dot Net Coder
Subscribe to get the latest posts sent to your email.