Following up on this and this, this is offered for a debounce lookup feature:
@code {
string searchQuery;
bool isSearching;
CancellationTokenSource currentSearchCts;
Location[] locations = new Location[0];
bool noResults;
string SearchQuery
{
get => searchQuery;
set
{
searchQuery = value;
if (!string.IsNullOrEmpty(searchQuery))
{
_ = SearchDebounced(searchQuery);
}
}
}
bool IsSearching => isSearching || currentSearchCts != null;
[Parameter]
public EventCallback<Location> LocationChanged { get; set; }
async Task GetLocalWeather()
{
isSearching = true;
var geolocation = await GetlocationService.GetLocationAsync();
var currentLocation = await
WeatherForecastService.GetLocationByGeolocation(geolocation.Lati...
isSearching = false;
await LocationChanged.InvokeAsync(currentLocation);
}
async Task SearchDebounced(string query)
{
try
{
noResults = false;
currentSearchCts?.Cancel();
currentSearchCts = new CancellationTokenSource();
var thisSearchToken = currentSearchCts.Token;
await Task.Delay(500);
if (!thisSearchToken.IsCancellationRequested)
{
var results = await WeatherForecastService.GetLocationByTest(query);
if (!thisSearchToken.IsCancellationRequested)
{
locations = results;
noResults = locations.Length == 0;
currentSearchCts = null;
}
}
StateHasChanged();
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.StackTrace);
}
}
void LocationSelected(ChangeEventArgs e)
{
var locationName = (string)e.Value;
var selectedLocation = locations.FirstOrDefault(l => CityState(l) == locationName);
if (selectedLocation != null)
{
searchQuery = null;
noResults = false;
locations = new Location[0];
LocationChanged.InvokeAsync(selectedLocation);
}
}
string CityState(Location location) => $"{location.LocalizedName},
{location.AdministrativeArea....
string GetSearchClass() => IsSearching ? "search-icon spinning" : "search-icon";
Some of the markup added:
<LocationSearch LocationChanged="LocationChanged" />
Later on there is talk of digging out the geolocation from the browser with JavaScript. Blazor has interop capabilities with JavaScript. AspNetMonsters.Blazor.Geolocation is a NuGet package that does the work already. An IJSRuntime is the type for a JavaScript interop like so:
var result = await jsRuntime.InvokeAsync<Location>
("AspNetMonsters.Blazor.Geolocation", requestId);
The parameters after the first one are generic parameters that will get past on to JavaScript and the generic parameter is the return type.
No comments:
Post a Comment