Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute async method on button click in blazor

I created a "Razor Components" project. I am trying to execute an asynchronous method when pressing a button, but could not figure out the syntax yet.

This is my Index.razor:

@page "/"
@inject GenericRepository<Person> PersonRepository 

@foreach (var person in persons)
{
    <button onclick="@(() => Delete(person.Id))">❌</button>
}

@functions 
{
    async void Delete(Guid personId)
    {
        await this.PersonRepository.Delete(personId);
    }
}

When I click the button, nothing happens. I tried various return types (e.g. Task) and stuff, but cannot figure out how to make it work. Please let me know if I need to provide more information.

Every documentation / tutorial only just works with non-async void calls on button click.

like image 756
ˈvɔlə Avatar asked Apr 03 '19 14:04

ˈvɔlə


2 Answers

You need to call the Delete method properly and make it return Task instead of void:

<button onclick="@(async () => await Delete(person.Id))">❌</button>

@functions {

    // ...

    async Task Delete(Guid personId)
    {
        await this.PersonRepository.Delete(personId);
    }
}
like image 88
DavidG Avatar answered Oct 09 '22 22:10

DavidG


@WoIIe, 1. The purpose of using a lambda expression as a value for the onclick attribute is so that you can pass a value to the Delete method. If you have already defined a person object in your code, you don't have to use a lambda expression. Just do this: onclick = "@Delete", and access person.Id from the Delete method.

  1. Did you click the button a second time? I believe that this code: await this.PersonRepository.Delete(personId); did execute, but you've seen no response on the GUI because the use of void, which is not recommended, requires you to call StateHasChanged(); manually to re-render. Note that StateHasChanged() has already been automatically called once when your method "ended", but since you're returning void and not Task, you should call StateHasChanged() once again to see the changes. But don't do it. See the answer by DavidG how to code properly.

This is also how you can code:

<button onclick="@Delete">Delete Me</button>

@functions {

    Person person = new Person();
    //....
    async Task Delete()
    {
        await this.PersonRepository.Delete(person.Id);
    }
}

More code as per request...

 foreach(var person in people)
    {
        <button onclick="@(async () => await Delete(person.Id))">Delete</button>
    }

@functions {
  // Get a list of People.
  List<Person> People ;

protected override async Task OnParametersSetAsync()
{
    People = await this.PersonRepository.getAll();
}

async Task Delete(Guid personId)
{
     await this.PersonRepository.Delete(personId);
}
}

Note: If you still have not solved your problems, show all your code

like image 17
enet Avatar answered Oct 09 '22 22:10

enet