Reputation: 4946
First, my JS:
class MyClass {
static myMethod() {
alert("TEST");
}
}
I have my JS runtime injected like this:
[Inject] protected IJSRuntime Js { get; set; }
I want to call a static method like this:
Js.InvokeVoidAsync("MyClass.myMethod");
but I get an error:
Microsoft.JSInterop.JSException: Could not find 'MyClass' in 'window'.
Is there a sane, reasonable way around this, or only by adding window.MyClass = MyClass to my JS?
Upvotes: 6
Views: 3349
Reputation: 3075
Try this (assuming server side Blazor).
In your _Host.cshtml file:
(function () {
window.MyClass = {
myMethod: function () {
return alert('TEST');
}
};
})();
in .razor file (at top):
@*Inject JSRuntime to allow JavaScript Interop *@
@inject IJSRuntime JSRuntime
In a method in your .razor file:
await JSRuntime.InvokeAsync<string>(
"MyClass.myMethod", null
);
See: Blazor JavaScript Interop
Upvotes: 4
Reputation: 7117
Yes, registering your method with the window object is correct.
The relevant part of the source code can be found here:
https://github.com/aspnet/Extensions/tree/master/src/JSInterop
Peeking into it you will find:
invokeJSFromDotNet: (identifier: string, argsJson: string) => { ... }
where
@param identifier Identifies the globally-reachable function to invoke.
Taking a look at the findJSFunction
you see the part that checks if the given identifier is registered with the window object and if not generates the error you see:
function findJSFunction(identifier: string): Function {
(...)
let result: any = window;
let resultIdentifier = 'window';
let lastSegmentValue: any;
identifier.split('.').forEach(segment => {
if (segment in result) {
lastSegmentValue = result;
result = result[segment];
resultIdentifier += '.' + segment;
} else {
throw new Error(`Could not find '${segment}' in '${resultIdentifier}'.`);
}
});
Upvotes: 0