Reputation: 790
I'm starting out with razor and trying to simply refresh my page with new data when I enter data in a search textbox.
My code - Component:
<div class="text-lg-start bg-blue-100">
<input class="border-4 w-1/3 rounded m-6 p-6 h-8 border-blue-300" @bind-value="SearchText" @bind-value:event="oninput" placeholder="Search by title" />
</div>
<table class="table">
<thead>
<tr>
<th>Btn</th>
</tr>
</thead>
<tbody>
@foreach (var movie in movies)
{
<tr>
<td>
<button class="btn btn-danger" @onclick="() => Hire(movie)">Rent</button>
</td>
</tr>
}
</tbody>
</table>
@code {
private Movie[]? movies;
[Parameter]
public string SearchText { get; set; } = "";
async Task Hire(Movie movie)
{
protected override async Task OnInitializedAsync()
{
movies = await MovieService.GetMovies(SearchText);
}
protected override async void OnParametersSet()
{
movies = await MovieService.GetMovies(SearchText);
}
}
My code - Service:
public class MovieService
{
private static readonly Movie[] MovieTest = new[]
{
new Movie(90, new List<string>(){"Horror"}, "The Skeleton Key"),
new Movie(120, new List<string>(){ "Science Fiction"}, "Star Wars")
};
public Task<Movie[]> GetMovies(string? search = null)
{
return Task.FromResult(MovieTest);
}
}
The only thing I want to achieve is that the screen gets refreshed based on what I put in the search box (typing 'SK' I would like to only see the skeleton key).
I found a working example where you filter the clientside data in the component, but I specifically wish to call the async service function, so that I can replace the body with an actual service call later. Anyone know what I am doing wrong or missing here?
P.S.
I tried adding @page "/{SearchText: string}"
besides my standard @page "/"
, but this causes a null-reference exception in the _Host.cshtml
Upvotes: 2
Views: 1388
Reputation: 11392
You can use @onchange
EventCallback to call your service when the input
element loses focus:
<input class="..." value="@SearchText" @onchange="HandleChange" placeholder="Search by title" />
@code {
private Movie[]? movies;
[Parameter]
public string? SearchText { get; set; }
protected override async Task OnInitializedAsync()
{
movies = await MovieService.GetMovies(SearchText);
}
private async Task HandleChange(ChangeEventArgs e)
{
SearchText = e?.Value?.ToString();
movies = await MovieService.GetMovies(SearchText);
}
}
You can also use @oninput
EventCallback in the same way:
<input class="..." value="@SearchText" @oninput="HandleChange" placeholder="Search by title" />
but this will trigger MovieService.GetMovies
immediately after every input change, so you shouldn't use it if your service makes actual http calls to a backend server or queries to a database.
Use whichever fits best for you scenario.
Upvotes: 3