Search code examples
c#asp.net-coreblazorblazor-webassembly

Blazor WebAssembly button onclick not triggered



TL;DR:
I've figured out I was confusing Blazor App Types and forgot to add `@rendermode InteractiveServer`.

I've a Client WebAssembly Blazor app and have a problem with onclick method not being triggered after clicking on button. This Blazor WebAssembly was added to existing ASP.NET Core WebAPI. It's .NET 8.
I've a dynamically created table containing some data fetched from service. Code doing this below:
private void FetchMails() {
    APIResponse result = MailArchiveService.GetMailMessages();
    if(!result.Success) {
        StatusMessage = result.GetStatusString();
    } else {
        Data = result.GetContent<List<MailDTO>>();
    }
}

APIResponse is a wrapper for communication between services, controllers and this Blazor app. It works and provided data are valid and displays correctly. My table generation looks like that:

@if (Data == null){
    <p><em>Loading...</em></p>
} else {
    <table class="table">
        <thead>
            <tr>
                <th>Sender</th>
                <th>Recipient</th>
                <th>Subject</th>
                <th>TemplateType</th>
                <th>Sent</th>
                <th>Actions</th>
            </tr>
        </thead>
        <tbody>
            @foreach(var record in Data) {
                <tr>
                    <td>@record.Sender.Email</td>
                    <td>@record.Recipient.Email</td>
                    <td>@record.Subject</td>
                    <td>@record.TemplateType.ToString()</td>
                    <td>@record.SentTime?.ToString("dd-MM-yyyy HH:mm:ss")</td>
                    <td>
                        <button @onclick="() => ViewMailContent(record.ID)">View</button>
                    </td>
                </tr>
            }
        </tbody>
    </table>
}

My onclick method looks like this:

public void ViewMailContent(int id) {
    Console.WriteLine($"ViewMailContent called with ID: {id}");
    //Display message content to user
}

My problem is that when I click the button nothing happens. I've added this WriteLine and placed breakpoint there and it's not even entering this method. For test reasons I've added another button outside of this table with const id and then it's working correctly. I do not get any bug, the app seems to do nothing, but don't freezes (I still can change tabs, and do other things).

I've tried solutions posted here. But it's not working.

I've tried changing the button in such ways:

  • Changed onclick to something like this:
    <button @onclick:event="onclick" @onclick="@(e => ViewMailContent(record.ID))">View</button>
  • Changing return type to EventCallback:
    <button @onclick="ViewMailContent(record.ID)">View</button>
    It was triggered when the page was loaded without user clicing
  • Adding mouseEventArgs (suggested here):
    <button @onclick="@(async (args) => ViewMailContent(record.ID))">View</button>
    <button @onclick="@(async (args) => ViewMailContent(args, record.ID))">View</button>
    Nothing changed
  • Adding such event (GPT suggestion):
    <button @onclick:event="onclick" @onclick="() => ViewMailContent(record.ID)">View</button>
    Nothing changed
  • Temporarily replaced handler with console.log:
    <button onclick="console.log('Clicked @record.ID')">View</button>
    I can see the message in browser's dev tools.

I got stuck and do not know what I'm doing wrong. I'm pretty new to Blazor.


Solution

  • The problem was that the I didn't have this:
    @rendermode InteractiveServer
    After adding it everything works just fine.