Calling an async function from a sync function

814 Views Asked by At

I am building a Blazor client side application. I am using MatBlazor components.

I have two MatSelectString controls on a page. The first one is used to select a category, and the second one to select products from the category. So I have it setu up like so:

<MatSelect Outlined="true" Label="Category" @bind-Value="@Category">
    <MatOptionString></MatOptionString>
    @foreach (var cat in GetCategories())
    {
        <MatOptionString Value="@cat">@cat</MatOptionString>
    }
</MatSelect>
<MatSelect Outlined="true" Disabled="@(!string.IsNullOrWhiteSpace(Category))" Label="Product" @bind-Value="@Product" >
    <MatOptionString></MatOptionString>
    @foreach (var prod in GetProducts(Category))
    {
        <MatOptionString Value="@prod">@prod</MatOptionString>
    }
</MatSelect>

Within the GetProducts(Category) code, I want to call the backend. The issue is that there is only a HttpClient.GetJsonAsync<>() method, that cannot be called from within a non-async method. But GetProduct() cannot be made async.

Things I have tried:

  • Putting the call to my function inside an async lambda (not allowed in foreach or in other code blocks)
  • Using Task.Result (it hangs)
  • Putting the back-end call in other component level async events (gets called multiple times)

Any ideas?

1

There are 1 best solutions below

5
On BEST ANSWER

You can use ValueChanged EventCallback:

<MatSelect 
    Outlined="true" 
    Label="Category" 
    ValueChanged="(string i)=>OnChangeCategory(i)"> @* <-- here *@
    <MatOptionString></MatOptionString>
    @foreach (var cat in GetCategories())
    {
        <MatOptionString Value="@cat">@cat</MatOptionString>
    }
</MatSelect>

@code
{
   protected async Task OnChangeCategory(string newValue)
   {
      this.Category = newValue;
      // call backend async tasks
      // ...
   }

Check it out at blazorfiddle.com