Search code examples
c#moduleblazorblazor-jsinterop

Blazor JSInterop with JSIsolation does not find window.ClassName


I am trying to call a method from a js file from Blazor

I keep getting the following error:

Error: Could not find 'TestClass.sayHello' ('TestClass' was undefined).

Js file:

class TestClass {
  sayHello(s) {
    console.log("Hello " + s);
    return true;
  }
}

window[TestClass.name] = new TestClass();

JsInterop.cs

    public IJSRuntime JsRuntime { get; }

    public ExampleJsInterop(IJSRuntime jsRuntime)
    {
        moduleTask = new (() => jsRuntime.InvokeAsync<IJSObjectReference>(
            "import", "./_content/JsTest.lib/exampleJsInterop.js").AsTask());
        JsRuntime = jsRuntime;
    }

    public async ValueTask<bool> SayHello(string name)
    {
        var module = await moduleTask.Value;
        return await module.InvokeAsync<bool>("TestClass.sayHello", name);
    }

When I use the jsRuntime directly it is working:

    public async ValueTask<bool> SayHello(string name)
    {
        var module = await moduleTask.Value;
        return await JsRuntime.InvokeAsync<bool>("TestClass.sayHello", name);
    }

I tried different names and const variables with no success.


Solution

  • You're mixing normal JS interop, where functions need to be in window, and JS isolation, where the method import expects a module.

    Try this instead in your JS file:

    export function sayHello(s) {
      console.log("Hello " + s);
      return true;
    }
    

    And call it directly:

        public async ValueTask<bool> SayHello(string name)
        {
            var module = await moduleTask.Value;
            return await module.InvokeAsync<bool>("sayHello", name);
        }
    

    This is a JS module, it only needs to export the functions that you want to call later.

    For more information: https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/call-javascript-from-dotnet?view=aspnetcore-6.0#javascript-isolation-in-javascript-modules