I am working on an app that lets users search our database. When a user enters search terms, the app hits an API endpoint, and returns the data. I then display the data.
When the API returns the data, I have a scoped service:
services.AddScoped<AppState>();
That keeps each returned dataset for use throughout all components of the app.
As soon as the SearchResults.razor
page loads, it grabs the results from my scoped service, then draws the rest of the page.
I need a "Loading" spinner to put in place of the data until the API returns the data, which could be a long time depending on the amount of data searched for.
My problem is that I cannot figure out what to use as a true/false "trigger" to use to know whether or not to show the data or loading spinner, or how to refresh the page once the API sends me it's data.
What I have below works only for the first initial search (from my Index.razor
page), but does not work for any of the included "filters" components.
SearchResults.razor:
@page "/searchresults"
@layout PageTopComponents
<Header.razor></Header.razor>
<LeftMenu.razor>
<FilterRazorComponent01.razor></FilterRazorComponent01.razor>
<FilterRazorComponent02.razor></FilterRazorComponent02.razor>
<FilterRazorComponent03.razor></FilterRazorComponent03.razor>
<FilterRazorComponent04.razor></FilterRazorComponent04.razor>
</LeftMenu.razor>
<MainContentComponent.razor>
// CONTENT HERE SHOULD BE VISIBLE WHEN DATA HAS ARRIVED, OTHERWISE IT SHOULD SHOW A "WAITING" SPINNER
@if(API_Data_Received != null && API_Data_Received.count > 0){
foreach(){
// API Retrieved Data Here
}
} else {
// Loading Spinner
}
<ContinueSearch.razor></ContinueSearch.razor>
<Paginator.razor @ref="PaginatorComponentReference">
<ChildContent>
// THIS IS WHERE I DISPLAY ALL SEARCH DATA ...
// CONTAINS: public Paginator PaginatorComponentReference;
</ChildContent>
</Paginator.razor>
</MainContentComponent.razor>
@code {
// code here ...
public async Task GetQueryStringValues()
{
Uri uri = navigationManager.ToAbsoluteUri(System.Net.WebUtility.UrlDecode(navigationManager.Uri));
Dictionary<string, StringValues> queryStrings = QueryHelpers.ParseQuery(uri.Query);
}
}
Paginator.razor:
<div> [ << ] [ < ] NAVIGATION [ > ] [ >> ] </div>
@ChildContent // Is "ChildContent" in SearchResults.razor
<div> [ << ] [ < ] NAVIGATION [ > ] [ >> ] </div>
Most of my included .RAZOR components do some kind of "filtering" and use the following:
String href = "/searchresults" + // other parameters here ...
NavigationManager.NavigateTo(href);
Meaning, whenever I "filter", I always hit the SearchResults.razor
page.
I believe I have tried some combination of await InvokeAsync(StateHasChanged);
in all of the override-able methods:
OnInitialized()
OnInitializedAsync()
OnParametersSet()
OnParametersSetAsync()
OnAfterRender()
OnAfterRenderAsync()
But nothing seems to work after that first load of SearchResults.razor
from my form entry in Index.razor
.
What do I need to do to get this to work? It seems simple enough, but I just cannot figure it out.