2

Here is what I've been doing in my Blazor server application -- pretty much every page needs to load some content by calling an API. I've been adding this async function inside the OnInitializedAsync() method.

However, recently, I've been reading articles that this is not the right place to do. It should've been done in the OnAfterRenderAsync() event. Here is an article talking about it towards the bottom: SpinKit Loading

I would like to know have I been doing it wrong? If so, why? Are any initial page data fetch should all be done in OnAfterRenderAsync()?

Thanks!

Franky
  • 1,262
  • 2
  • 16
  • 31

3 Answers3

2

You only have to call it in OnAfterRenderAsync if you are calling JavsScript. If you don't have any [Parametet] properties, or you only need to call the API once then OnInitializedAsync is fine. If it is a page with route parameters, or a component with [Parameter] properties and the call to the API depends on those properties, then you need to call it in SetParametersAsync.

Peter Morris
  • 20,174
  • 9
  • 81
  • 146
1

As you know in Blazor server application every lifecycle methods are called twice, so best practice would be calling database, long-running calculation and calling JavaScript will be in OnAfterRenderAsync/OnAfterRender method, check if it renders first time using firstRender flag, otherwise calling database/long-running calculation will be called unnecessary twice. for example

protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
               // calling database/long-running calculation/calling JavaScript
        }
    }

If you want to read more about methods lifecycle: https://learn.microsoft.com/en-us/aspnet/core/blazor/components/lifecycle?view=aspnetcore-3.1

Mofaggol Hoshen
  • 686
  • 1
  • 7
  • 20
  • Specifically, all lifecycle methods _except_ `OnAfterRender{Async}` are called twice on navigation _only if_ the render mode is set to `ServerPrerendered`. – Robula Aug 04 '22 at 13:47
0

I feel this question has not an accurate response so I will try to detail.

First to know is about what @Robula commented. Methods involved in component instance creation (OnInitialized, OnParametersSet) are called twice always that we are using "ServerPrerendered". More info

I don't think @PeterMorris answer is accurate since I dont feel JS or Parameter dependencies are involved in this decision of calling an API or long-running ops in one or another method.

Being coherent the most optimal implementation should be call those in the OnAfterRender/OnAfterRenderAsync method and only under the flag "firstRender == true".

As @MofaggolHoshen said.

<div class="container">
    <div class="row">
        @Text
    </div>
</div>

@code{
    private string Text { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            HttpClient client = new HttpClient();
            Text = await client.GetStringAsync("https://filesamples.com/samples/document/csv/sample2.csv");
            StateHasChanged();
        }
        await base.OnAfterRenderAsync(firstRender);
    }

}

This way we ensure Api calls or long-running ops are called only one time and rendered asynchronously.

Sam
  • 1,459
  • 1
  • 18
  • 32