javascriptblazorblazor-webassembly

Onclick event not working in Blazor Web Assembly 8.0


I am studying a Blazor course and I noticed the button click event does not trigger on button click. I created a simple Blazor web assembly 8.0 project to confirm the issue. I noticed on button click nothing happened.

I added @rendermode InteractiveServer to my test page and also these methods to my program.cs, but nothing happened.

builder.Services.AddRazorComponents().AddInteractiveServerComponents()

app.MapRazorComponents<App>().AddInteractiveServerRenderMode();

Program.cs

using BlazorApp1.Components;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorComponents();
builder.Services.AddRazorComponents().AddInteractiveServerComponents();

var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
  app.UseExceptionHandler("/Error", createScopeForErrors: true);
  app.UseHsts();
}

app.MapRazorComponents<App>().AddInteractiveServerRenderMode();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.MapRazorComponents<App>();
app.Run();

Test.razor

@page "/test"
@rendermode InteractiveServer
@inject IJSRuntime JsRuntime
<h3>Test JavaScript Interop</h3>
<button type="button" @onclick="TestJsInterop">Click Me</button>

@code {
  private async Task TestJsInterop()
  {
    // Call the custom JS function showCustomAlert
    await JsRuntime.InvokeVoidAsync("showCustomAlert", "Hello from custom JS interop!");
  }
}
window.showCustomAlert = function (message) {
  alert(message); // This is the native JS alert function
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>BlazorApp</title>
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/site.css" rel="stylesheet" />
</head>
<body>
    <app>
        <!-- The component rendered in InteractiveServer mode will be mounted here -->
    </app>
    <script src="_framework/blazor.server.js"></script>
<script src="js/spp.js"></script>

</body>
</html>

The weird part is that the counter button works perfectly well in the counter page.

I also Updated Routes element in App.razor file with <Routes @rendermode=RenderMode.InteractiveServer /> and <script src="_framework/blazor.web.js"></script>

I want the button click event to display an alert with message "Hello from custom JS interop!"

Please help me fix this error as I can't forge ahead with my Blazor tutorial.


Solution

  • There are two Visual Studio project templates, which can refer to a .NET 8 Blazor WebAssembly App:

    The provided code snippets don't make sense for any of the two project templates. For example:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <base href="/" />
        <link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
        <link rel="stylesheet" href="app.css" />
        <link rel="stylesheet" href="BlazorApp1.styles.css" />
        <link rel="icon" type="image/png" href="favicon.png" />
        <HeadOutlet @rendermode="InteractiveWebAssembly" />
    </head>
    
    <body>
        <Routes @rendermode="InteractiveWebAssembly" />
        <script src="_framework/blazor.web.js"></script>
    </body>
    
    </html>
    
    using BlazorApp1.Client.Pages;
    using BlazorApp1.Components;
    
    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    builder.Services.AddRazorComponents()
        .AddInteractiveWebAssemblyComponents();
    
    var app = builder.Build();
    
    // Configure the HTTP request pipeline.
    if (app.Environment.IsDevelopment())
    {
        app.UseWebAssemblyDebugging();
    }
    else
    {
        app.UseExceptionHandler("/Error", createScopeForErrors: true);
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }
    
    app.UseHttpsRedirection();
    
    app.UseStaticFiles();
    app.UseAntiforgery();
    
    app.MapRazorComponents<App>()
        .AddInteractiveWebAssemblyRenderMode()
        .AddAdditionalAssemblies(typeof(BlazorApp1.Client._Imports).Assembly);
    
    app.Run();
    

    I chose Blazor Web App when creating the project.

    If this is true, then I assume that you created a Blazor Web App with incorrect render mode and/or Per page / component interactivity location. For apps with WebAssembly render mode this means that only .razor files in the Client project with @rendermode InteractiveWebAssembly will support @onclick, JSInterop or any other interactivity. The @rendermode declaration was missing in Test.razor, and maybe you added some other unnecessary stuff while troubleshooting and using an old or confusing Blazor tutorial for a different app type.

    Currently, the app is probably in a messy and invalid state, which makes it easier for you to start from scratch. My recommendation is to create A Blazor Web App with WebAssembly render mode and Global interactivity location. Then, add Test.razor to the Pages folder in the Client project:

    @page "/test"
    
    @inject IJSRuntime JsRuntime
    
    <h3>Test JavaScript Interop</h3>
    
    <button type="button" @onclick="TestJsInterop">Click Me</button>
    
    <script suppress-error="BL9992">
        window.showCustomAlert = function (message) {
            alert(message); // This is the native JS alert function
        }
    </script>
    
    @code {
        private async Task TestJsInterop()
        {
            // Call the custom JS function showCustomAlert
            await JsRuntime.InvokeVoidAsync("showCustomAlert", "Hello from custom JS interop!");
        }
    }
    

    This should work.