0

I'm messing around with the default Blazor WASM scaffolded application from Visual Studio 2022 (.NET 6).

Specifically just trying to call a JS function (that's in its own file) from a method in one of the components.

Is there a specific place to put custom JS references? Some special way to load them so the file is instantly loaded/brought down into the browser?

On the first load, my JavaScript function can't be found. (it looks like the file isn't even under "Sources" in my browser inspector)

I hit a button in the component/on the page, it calls a C# method, which then tries to invoke the JS function. But it fails and the little banner at the bottom of the screen pops up (seems like the default for the scaffolded app?) and I hit the "Reload" link...and then boom...it can find my JS function suddenly the next time I hit the button.

enter image description here

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Could not find 'setElementTextById' ('setElementTextById' was undefined).
      Error: Could not find 'setElementTextById' ('setElementTextById' was undefined).

My index.html file looks like (only thing I changed was a script reference to my JS file):

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <title>BlazorWASM</title>
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/app.css" rel="stylesheet" />
    <link href="BlazorWASM.styles.css" rel="stylesheet" />

</head>

<body>
    <div id="app">Loading...</div>

    <div id="blazor-error-ui">
        An unhandled error has occurred.
        <a href="" class="reload">Reload</a>
        <a class="dismiss"></a>
    </div>

    <script src="_framework/blazor.webassembly.js"></script>
    <script type="text/javascript" src="js/site.js"></script>

</body>

</html>


The JavaScript file:

window.setElementTextById = (id, text) => {
    console.log("inside setElementTextById");
    document.getElementById(id).innerText = text;
};

I have also tried (with the same error results):

function setElementTextById(id, text) {
    console.log("inside setElementTextById");
    document.getElementById(id).innerText = text;
}
netdev19
  • 51
  • 1
  • 5
  • Follow the instructions given in the Microsoft docs to the T. One problem that I see here is that you are not "exporting" the functions. – Mayur Ekbote May 01 '23 at 08:56

1 Answers1

0

Calling javascript function from blazor code is greatly explained in microsoft Doc: https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/call-javascript-from-dotnet?view=aspnetcore-7.0

Javascript files can be loaded from different positions as explained here: https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/?view=aspnetcore-7.0#location-of-javascript

You load a script from an external JavaScript file (.js) and a "js" folder inside wwwroot (as you do) is a good option.
As MS suggest, remember to:

Place the JavaScript (JS) tags (...) with a script source (src) path inside the closing tag after the Blazor script reference.

Be sure that the element you are trying to modify is rendered when you call your function. (i.e. Call it from a button event handler or in:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    await JS.InvokeVoidAsync("setElementTextById", "my_element", "test");
}

This code worked for me with both the .js files you provided:

@page "/index"
@inject IJSRuntime JS

<PageTitle>Index</PageTitle>

<h1>Test Function</h1>

<div id="my_element"></div>
<button class="btn btn-primary" @onclick="SetText">SetText</button>

@code {

    private async Task SetText()
    {
        await JS.InvokeVoidAsync("setElementTextById", "my_element", "Test successful");
    }

}
Nicola P
  • 81
  • 3