1

I try to show a spinner while loading the data. The spinner worked just fine, as long as i didn't explictly made all the calls asnyc. But since I change to async calls, it seems that the StateChanges of the two variable isLoading and emptyResult won't be recognized. Everything else just runs as it should and after a view seconds my the table is shown, but i never get the spinner. What am I missing here?

<EditForm Model="@parameter" OnValidSubmit="@Submit">
 
...
</EditForm>

@if (isLoading && !emptyResult)
{
    <div class="spinner"></div>
}
else if(!isLoading && emptyResult)
{
    <div>
        <span class="text-danger">
            No data for given parameters.
        </span>
    </div>
}
else if (data != null && !isLoading && !emptyResult)
{
    //Table of data
}


@code{
    private MyParameter parameter = new MyParameter();
    private List<CustomObject> data;

    private bool isLoading = false;
    private bool emptyResult = false;

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
    }

    private async Task Submit()
    {
        emptyResult = false;
        isLoading = true;
        await LoadDataAsync();
        isLoading = false;
    }
        
    private async Task LoadDataAsync() 
    {
       data = await service.GetData(parameter);
       if(data is null)
       {
           emptyResult = true;
       }
       else { 
       //Some calculation on data
       }
    }
 }
    
0

2 Answers 2

1

I took your page and made it standalone and added a bit more display logic. Here's my version which I think works as you want it to.

@page "/"

<div class="m-2">
<EditForm Model="@parameter" OnValidSubmit="@Submit">
<div class="bg-info p-2">
    Some edit fields
</div> 
<div class="p-2">
    <button class="btn btn-primary" type="submit">Submit</button>
</div> 
</EditForm>
</div>

@if (isLoading)
{
    <div class="spinner"><h3 class="text-danger">Spinning....</h3></div>
}
else if(emptyResult)
{
    <div>
        <span class="text-danger">
            No data for given parameters.
        </span>
    </div>
}
else if (data != null)
{
    <div>
        <span class="text-white bg-dark p-2">
            Data : @data.Value
        </span>
    </div>
}

else
{
    <div>
        <span class="text-white bg-danger p-2">
            No Data to Display
        </span>
    </div>
}

@code{
    private MyData parameter = new MyData();
    private MyData? data;
    private bool toggle;

    private bool isLoading = false;
    private bool emptyResult = false;

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
    }

    private async Task Submit()
    {
        emptyResult = false;
        isLoading = true;
        await LoadDataAsync();
        isLoading = false;
        toggle = !toggle;
    }

    private async Task LoadDataAsync() 
    {
        //  emulate an async call
        await Task.Delay(1000);
        data = toggle
            ? data = null
            : data = new MyData {Value = $"updated at {DateTime.Now.ToLongTimeString()}"};

        if(data is null)
            emptyResult = true;
        else 
            emptyResult = false;
    }

    public class MyData
    {
        public string Value { get; set; } = string.Empty;
    }

 }
Sign up to request clarification or add additional context in comments.

Comments

1

The symptoms indicate that await service.GetData(parameter) is not async (enough). Ensure your action releases the Thread, do that in the top UI method:

private async Task Submit()
{
    emptyResult = false;
    isLoading = true;
    await Task.Delay(1);    // add this
    await LoadDataAsync();
    isLoading = false;
}

2 Comments

This worked. But I don't really get why my GetData shouldn't be async enough. This is a "public asnyc Task<List<...>> GetData(...)" But I think I could optimise and async some more stuff within this method?!
We'd have to see the contents of GetData(). But it doesn't really matter. You have a UI requirement, solve it in the UI.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.