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

  1. Open Visual Studio 2022 and click the Create a new project button.
  2. Select the Razor Class library project and click the Next button.
  3. Enter Dnc.Common.Razor in the Project name textbox and Loading in the Solution name and click the Next button.
  4. Select .NET 8.0 as the version of the Framework to use and click the Create button.
blazor loading spinner

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.

  1. Right-click the CS.Common.Razor project and add a new project folder called Wrapper
  2. Right-click the Wrapper folder and  add a class that derives from ComponentBase named DncWrapperComponent
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.WebAppproject and select the Add, Project Reference option from the menu and check the Dnc.Common.Razorcheckbox 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.

blazor loading spinner

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

data displayed

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?

Buy Me a Coffee Donate via PayPal

Discover more from Dot Net Coder

Subscribe to get the latest posts sent to your email.

Author

Ads Blocker Image Powered by Code Help Pro

Ads Blocker Detected!!!

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

Powered By
100% Free SEO Tools - Tool Kits PRO