Why isn't Blazor able to find a JavaScript function declared in index.html?

116 Views Asked by At

I am trying to call a JavaScript function in a .razor component:

This is what it's been declared like in index.html:

window.getIsBrowserChromium = function () {
  return !!navigator.userAgentData &&
         navigator.userAgentData.brands.some(data => data.brand == 'Chromium');
}

This is how it is being called:

public async Task<bool> GetIsChromium() =>
  await JSRuntime.InvokeAsync<bool>("window.getIsBrowserChromium");

And this is how it's being used in the MainLayout:

protected async override Task OnInitializedAsync()
    var isChromiumBrowser = await BrowserService.GetIsChromium();
    if (!isChromiumBrowser)
    {
      ShowBrowserWarning();
    }
}

But I'm getting this error: enter image description here enter image description here

I tried using OnAfterRenderAsync() instead but same results.

1

There are 1 best solutions below

1
On

The error says it can't find window.getIsBrowserChromium, so you can't have it registered properly.

I've moved your JS code into wwwroot/site.js, and then added the reference to _hosts.cshtml.

@page "/"
@using Microsoft.AspNetCore.Components.Web
@namespace SO77084016.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<!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="css/bootstrap/bootstrap.min.css" />
    <link href="css/site.css" rel="stylesheet" />
    <link href="SO77084016.styles.css" rel="stylesheet" />
    <link rel="icon" type="image/png" href="favicon.png"/>
    <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>
<body>
    <component type="typeof(App)" render-mode="ServerPrerendered" />

    <div id="blazor-error-ui">
        <environment include="Staging,Production">
            An error has occurred. This application may no longer respond until reloaded.
        </environment>
        <environment include="Development">
            An unhandled exception has occurred. See browser dev tools for details.
        </environment>
        <a href="" class="reload">Reload</a>
        <a class="dismiss"></a>
    </div>

    <script src="_framework/blazor.server.js"></script>
    <script src="site.js"> </script>
</body>
</html>

To demo the check. I've added the JSInterop call to OnAfterRenderAsync. As this mutates the state of the component you need to call StateHasChanged to reflect that change in the UI.

@page "/"
@inject IJSRuntime _js

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.
<div class="bg-dark text-white m-2 p-2">
    <pre>Is Chromium : @_isChromium </pre>
</div>
@code {
    public bool? _isChromium = null;

    protected async override Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            _isChromium = await _js.InvokeAsync<bool>("window.getIsBrowserChromium");
            // Mutated State so need to refresh the UI
            StateHasChanged();
        }
    }
}

Run in Edge : True Firefox: False