Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blazor - Display wait or spinner on API call

Tags:

c#

blazor

In my Blazor app I am making an API call to a back end server that could take some time. I need to display feedback to the user, a wait cursor or a "spinner" image. How is this done in Blazor?

I have tried using CSS and turning the CSS on and off but the page is not refreshed until the call is completed. Any suggestions would be greatly appreciated.

@functions {     UserModel userModel = new UserModel();     Response response = new Response();     string errorCss = "errorOff";     string cursorCSS = "cursorSpinOff";      protected void Submit()     {         //Show Sending...         cursorCSS = "";         this.StateHasChanged();         response = Service.Post(userModel);         if (response.Errors.Any())         {             errorCss = "errorOn";         }         //turn sending off         cursorCSS = "cursorSpinOff";         this.StateHasChanged();     } } 
like image 593
David23g Avatar asked Jun 14 '19 20:06

David23g


People also ask

Why doesn't the spinner appear in my Blazor Server App?

Because Blazor Server apps use pre-rendering the spinner will not appear, to show the spinner the long operation must be done in OnAfterRender.

How to show/hide spinner from other components in web application?

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. Feel free to comment and suggests changes . Happy Coding!

Why is Blazor blocking the renderer?

Blazor will update the UI as soon as the render engine gets to run on its Thread again. Much like any other UI framework all UI operations have to be done on the main thread. But your events are also running (initially) on that same thread, blocking the renderer. To resolve that, make sure your events are async by returning async Task.

When to call statehaschanged () in Blazor?

Blazor will (conceptually) call StateHasChanged () after initialization and before and after events. That means you usually don't need to call it, only when your method has several distinct steps and you want to update the UI in the middle do you need to call it.


1 Answers

Option 1: Using Task.Delay(1)

  • Use an async method.
  • Use await Task.Delay(1) or await Task.Yield(); to flush changes
private async Task AsyncLongFunc()    // this is an async task {     spinning=true;     await Task.Delay(1);      // flushing changes. The trick!!     LongFunc();               // non-async code     currentCount++;     spinning=false;     await Task.Delay(1);      // changes are flushed again     } 

Option 1 is a simple solution that runs ok but looks like a trick.

Option 2: Using Task.Run() (not for WebAssembly)

On January'2020. @Ed Charbeneau published BlazorPro.Spinkit project enclosing long processes into task to don't block the thread:

Ensure your LongOperation() is a Task, if it is not, enclose it into a Task and await for it:

async Task AsyncLongOperation()    // this is an async task {     spinning=true;     await Task.Run(()=> LongOperation());  //<--here!     currentCount++;     spinning=false; } 

Effect

a spinner loading data

Spinner and server side prerendering

Because Blazor Server apps use pre-rendering the spinner will not appear, to show the spinner the long operation must be done in OnAfterRender.

Use OnAfterRenderAsync over OnInitializeAsync to avoid a delayed server-side rendering

    // Don't do this     //protected override async Task OnInitializedAsync()     //{     //    await LongOperation();     //}      protected override async Task OnAfterRenderAsync(bool firstRender)     {         if (firstRender)         {                         await Task.Run(()=> LongOperation());//<--or Task.Delay(0) without Task.Run             StateHasChanged();         }     } 

More samples

Learn more about how to write nice spinner you can learn from open source project BlazorPro.Spinkit, it contains clever samples.

More Info

See Henk Holterman's answer with blazor internals explanation.

like image 151
dani herrera Avatar answered Sep 22 '22 21:09

dani herrera