3

I want to load data from an API and display a loading animation.

When I load in OnInitializedAsync() the animation is shown but the API call is made twice.

public class MyComponent : ComponentBase
{
    private bool isLoading;
    private List<MyData> myData;

    protected override async Task OnInitializedAsync()
    {
        isLoading = true;
        myData = await _myService.GetDataAsync();
        isLoading = false;
    }
}

When I load in OnAfterRenderAsync() the API call is made once but the UI is not updated.

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            isLoading = true;
            myData = await _myService.GetDataAsync();
            isLoading = false;

            StateHasChanged();
        }
    }

How can I load the data only once and show the loading animation/update the UI properly?

jeb
  • 848
  • 5
  • 16

2 Answers2

0

Either follow the steps stated here or simply add an if-statement in OnInitializedAsync checking if myData is empty and then fetch the data from the API.

Zita
  • 121
  • 1
  • 9
  • Yes, one could swap the servermode to RenderMode.Server but I don't want to loose the benefits of prerendering if I could avoid it. Checking the myData is not an option since both calls have different variables. Both counts would be 0. I tested it. – jeb Mar 28 '23 at 08:37
  • Did you read the entire answer? You don't have to disable pre-rendering, simply check if ``IJSRuntime`` has been initialized, it's always false in first iteration. – Zita Mar 28 '23 at 09:04
  • I am not sure if i understand you correctly. Shouldn't the JsRuntime only be available after Render? If i check the (JsRuntime != null) in OnInitialisedAsync() it is null both times. Or do you mean something else ? – jeb Mar 28 '23 at 09:54
  • My bad, it was quite some time since I last did this. You need to use reflection in order to check if JsRuntime has been initialized. ``PropertyInfo prop = js.GetType().GetProperty("IsInitialized"); bool haveInitialized = (bool)prop.GetValue(js);`` – Zita Mar 29 '23 at 07:15
0

This was actually straight forward.

If you call StateHasChanged() each time the bool is set the UI is updated properly in OnAfterRenderAsync

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        isLoading = true;
        StateHasChanged();
        myData = await _myService.GetDataAsync();
        isLoading = false;
        StateHasChanged();
    }
}
jeb
  • 848
  • 5
  • 16