Loader


Quick start

You can use the Loader component to show a loading indicator while waiting for data to load and display a message when an error occurs.

Global templates configuration

You can configure the global templates for the loader component using the BdkLoaderOptions class.

The following example shows how to configure the global templates for the loader component.

Loading content template example
BdkLoaderOptions.Loading.ChangeContent<LoadingContent>();
LoadingContentExample.razor
<div class="d-flex flex-column align-items-center justify-content-center">
    <div class="spinner-border text-danger" role="status">
        <span class="visually-hidden">Loading...</span>
    </div>
    
    <div class="mt-3">@(string.IsNullOrEmpty(Message) ? "Loading..." : Message)</div>
</div>

@code 
{
    [Parameter] public string Message { get; set; } = string.Empty;
}

The component created to be used as LoadingContent needs to have a parameter called Message of type string.

You can register a RenderFragment string or MarkupString in place of the component type, noting that only MarkupString does not support receiving the Message defined in the BdkLoader component.

Similarly, the registration of the component type to be used in error cases needs to have a parameter called ErrorResult of type BdkLoaderErrorResult, which can be used to access the exception that occurred and check if the retry button will be displayed. Below is an example of the registration and usage of this component:

Error content template example
BdkLoaderOptions.Error.RegisterContent<Exception, ErrorContentExample>();

You can register an ErrorContent for a specific exception type.

ErrorContentExample.razor
<div class="d-flex flex-column align-items-center justify-content-center">
    <div class="mt-3 text-danger">
        @ErrorResult.Exception.Message
    </div>

    @if (ErrorResult.Loader.CanRetry)
    {
        <div class="mt-3">
            <button class="btn btn-primary" @onclick="ErrorResult.Loader.ReloadAsync">@ErrorResult.Loader.CanRetryTitle</button>
        </div>
    }
</div>

@code
{
    [Parameter] public required BdkLoaderErrorResult ErrorResult { get; set; }
}

Basic

  • 1e882a60-5ed7-486c-9681-67433b32d5d1 - 09/29/2024 03:29:15 +00:00
  • 94772038-5fb1-446a-8bc3-1832a81e8afe - 09/29/2024 03:29:15 +00:00
  • 1ee174dd-bd75-428d-ad64-bc7b68bfaf6f - 09/29/2024 03:29:15 +00:00
  • 4258a5d9-6356-417d-8761-3827fe430ea7 - 09/29/2024 03:29:15 +00:00
  • 982f153c-03dd-4fa2-abe3-9470f3e0e2df - 09/29/2024 03:29:15 +00:00
Blazor
@inject ISubjectService Service

<BdkLoader Load="Service.ListAsync">
    <ul>
        @foreach (var item in context)
        {
            <li>@item.Id - @item.CreatedOn</li>
        }
    </ul>
</BdkLoader>

Basic: no result

Attention: the BdkLoader context will be null, this mode can be used when a return value is not necessary.

Content displayed after loading

Blazor
@inject ISubjectService Service

<BdkLoader T="object?" Load="LoadAsync">
    <p>
        Content displayed after loading
    </p>
</BdkLoader>

@code
{
    private async Task<object?> LoadAsync()
    {
        await Service.ProcessAsync();
        return null;
    }
}

Basic with custom loading message

  • 1bb41d30-bd60-4110-8eb9-4e792a2b968f - 09/29/2024 03:29:15 +00:00
  • 4c0db082-5781-4982-a6f2-a21d9eb775e6 - 09/29/2024 03:29:15 +00:00
  • b5540511-388b-4eff-b8d5-ad11b4e935c3 - 09/29/2024 03:29:15 +00:00
  • 287a6f0a-5d37-472b-85da-bdf6b42d5f7e - 09/29/2024 03:29:15 +00:00
  • 0dea515c-29ca-44ab-bf98-20477c2a1d9d - 09/29/2024 03:29:15 +00:00
Blazor
@inject ISubjectService Service

<BdkLoader Load="Service.ListAsync" Message="This is a custom message">
    <ul>
        @foreach (var item in context)
        {
            <li>@item.Id - @item.CreatedOn</li>
        }
    </ul>
</BdkLoader>

Basic with error

Subject not found in the database
Blazor
@inject ISubjectService Service

<BdkLoader Load="LoadAsync">
    <ul>
        @foreach (var item in context)
        {
            <li>@item.Id - @item.CreatedOn</li>
        }
    </ul>
</BdkLoader>

@code
{
    private async Task<ResponseItem[]> LoadAsync()
    {
        await Service.ProcessAsync(throwErrorAfterProcess: true); // Simulate error
        return await Service.ListAsync();
    }
}

Basic with error and CanRetry

Subject not found in the database
Blazor
@inject ISubjectService Service

<BdkLoader Load="LoadAsync" CanRetry CanRetryTitle="Retry">
    <ul>
        @foreach (var item in context)
        {
            <li>@item.Id - @item.CreatedOn</li>
        }
    </ul>
</BdkLoader>

@code
{
    private async Task<ResponseItem[]> LoadAsync()
    {
        await Service.ProcessAsync(throwErrorAfterProcess: true); // Simulate error
        return await Service.ListAsync();
    }
}

Basic with error, CanRetry and local custom ErrorContent

Subject not found in the database
Blazor
@inject ISubjectService Service

<BdkLoader Load="LoadAsync" CanRetry CanRetryTitle="Retry">
    <ErrorContent Context="errorResult">

        <div class="d-flex flex-column align-items-center justify-content-center">
            <div class="mt-3 text-info">
                @errorResult.Exception.Message
            </div>

            @if (errorResult.Loader.CanRetry)
            {
                <div class="mt-3">
                    <button class="btn btn-danger" @onclick="errorResult.Loader.ReloadAsync">@errorResult.Loader.CanRetryTitle</button>
                </div>
            }
        </div>
        
    </ErrorContent>
    <ChildContent>
        Content here
    </ChildContent>
</BdkLoader>

@code
{
    private async Task<ResponseItem[]> LoadAsync()
    {
        await Service.ProcessAsync(throwErrorAfterProcess: true); // Simulate error
        return await Service.ListAsync();
    }
}

Basic with PreserveState

When the PreserveState mode is enabled, the BdkLoader will attempt to preserve the result of the Load function, avoiding going back to the server and causing an unwanted “Reload.”

  • Item: 7433e39b-bddd-4bc0-b587-2fb9c7207c8f
  • Item: ada60753-0b4a-4201-96e4-8ae523ad6e95
  • Item: 8d3f9e10-b1de-498a-b9d5-84a1df4deda3
  • Item: 98f95256-f456-4e97-81e0-eea152b1f3f2
  • Item: de3025b1-bf41-4f40-9f8c-918648b57782
Blazor
@inject ISubjectService Service

<BdkLoader Load="Service.ListAsync" PreserveState >
    <ul>
        @foreach (var result in context)
        {
            <li>Item: @result.Id</li>
        }
    </ul>
</BdkLoader>

Basic with PreserveState and not result

Content displayed after loading

Blazor
@inject ISubjectService Service

<BdkLoader T="object?" Load="LoadAsync" PreserveState>
    <p>
        Content displayed after loading
    </p>
</BdkLoader>

@code
{
    private async Task<object?> LoadAsync()
    {
        await Service.ProcessAsync();
        return null;
    }
}