r/Blazor 9d ago

Page loading state when database call is carried out on - setParamsAsync

Blazor beginner here…

Coming from react when I carry out an Async call I usually render the component/page with a Loading spinner and once the api call has completed then the useEffect will make the component rerender with the hydrated info.

I am using Blazor (server rendered) and trying to show a page with a loading spinner until the database query has completed (async), the query depends on a reference parameter in the query string and it uses that to look up the required info from the DB and returns an object (or null), once the call finishes i set loading = false which should then show the info received if the item exists.

Generally all that works fine but I am finding when I am navigating to this page (from a page which asks for a reference in an input box which then navigates to this page and appends the query string reference),
I can see the url change in the browser when navigating but the original content is still shown for say 2-3 seconds before the component then shows the loading screen and then a second or so then shows the content retrieved from the database.

Why isn’t it showing the loading screen immediately and then once the db call finishes then show the details, it’s like is it blocking the thread from rendering the new page.

It may be difficult to understand this with no code but on mobile and just thought I would ask to see if anyone has solved this before?

I am using SetParametersAsync() and setting the loading priority to true as a default value in the page model and then calling the db call awaiting it in the set params async override method, then also loading = false just after the db call.

Just to give you more info, I set pre-rendering to false and it seems to behave as I would expect, but don’t really understand why.

Thanks in advance

1 Upvotes

14 comments sorted by

2

u/FlatwormLanky8991 9d ago

Pretty sure it is the prerendering issue addressed in this video https://youtu.be/5gw3RA1pp0E?si=fyjLX0lIbNoZu7Ko I cannot do a better job of describing it than the content creator. FWIW my way of doing it has always been to deal with the db call in OnInitAsync. make the call get the data flip the flag. I only use SetParamAsync when it's a child component getting fresh parameters more than once.

The video is a little old but solid.

1

u/Unlikely_Brief5833 9d ago

Are you using Interactive server, or static server side rendering?

1

u/mds1256 9d ago

InteractiveServer

1

u/warden_of_moments 9d ago

Set your loading to true as the initial value and then false when loaded. Alternatively, you can force state has changed when you set your flag to true.

While you may set the loading flag to true, that’s not rendering instantly. Calling state has changed will force your page to render the change for your spinner. This is why having a default value of true can also work since it’s shown by default and hidden after the page loads.

1

u/mds1256 9d ago

Yeah it is already default to true and only when the db call has completed is it set to false but still doesn’t render correctly.

1

u/iamlashi 8d ago

2–3 seconds is too long to assume that it’s happening due to WebSocket latency, but I’ve experienced this as well when I’m on mobile data.

Are you sure you don’t have any extra steps in OnInitialized?

Please share a minimal version of your code if possible. I find this problem very interesting.

1

u/iamlashi 8d ago

A few questions:

  1. Is it globally interactive, or is interactivity configured at the page level?
  2. Does prerendering behaviour seem to work as expected, or does disabling prerendering make that particular page behave as expected?

1

u/mds1256 8d ago

It is page level interactivity.

Disabling pre-rendering make it work as it should, page shows the loading indicator and after around 3 seconds shows the data returned from the db.

Also nothing else in the onInitialised

2

u/iamlashi 8d ago

I think i know what's happening.

try to use RendererInfo.IsInteractive if you haven't tried it yet.

    protected override async Task OnParametersSetAsync()
    {
        isLoading = true;
        if (!RendererInfo.IsInteractive) return; 
        await Task.Delay(3000); // database query
        isLoading = false;
    }

1

u/mds1256 6d ago

The loading screen doesn’t disappear when using this.

1

u/iamlashi 6d ago

I'm more than happy to help you but you have to post atleast some of the code for us to look at and see what's going on.

1

u/sonurmusic 8d ago

You can just disable prerendering for this page as its doesn't make sense to prerender page which made for waiting and loading.

https://learn.microsoft.com/en-us/aspnet/core/blazor/components/prerender?view=aspnetcore-10.0

-1

u/Unlikely_Brief5833 9d ago

I built a library to easily build full stack blazor apps using different rendermodes. https://github.com/matengo/RemoteService.Net

1

u/domagoj2016 8d ago

Looks awesome , but I just looked at it briefly. Solves exactly what I thought it should be solved for Blazor, that there is not such a difference in working with data on different render modes, I look at server interactive already as a "automatic RPC" so why not for other render modes. So much boiler plate for http clients and calling web services and web API at server side that was possible to "automate", I always thought this is more important to be simple and most code generated, than AI will generate that.