Reputation: 91
I created a simple Blazor MAUI project. I added a simple Razor class library, which contain two JavaScript files, a simple razor component with three buttons, and two C# wrapper classes for JavaScript methods call. One of the JavaScript file use the export keyword and the other is not. The first wrapper class uses the default method code generated
{
var module = await moduleTask.Value;
return await module.InvokeAsync<string>(“showPrompt”, message);
}
The second wrapper uses JSRuntime JS
{
return await JS.InvokeAsync<string>(“showPrompt”, message);
}
My basic Razor component is defined as the following:
@inject ExampleJsInterop exampleJsWithModule
@inject IJSRuntime js
@inject ExampleJsInteropWithJSRunTime exampleJsRunTime
<div class=“my-component”>
This component is defined in the <strong>RazorClassLibrary</strong> library.
<button class=“btn btn-primary” @onclick=“CallJSFunctionFromCSWithModule”>Call JS function from C# with Module</button>
<button class=“btn btn-primary” @onclick=“CallJSFunctionFromCSWithJSruntime”>Call JS function from C# With JSruntime</button>
<button class=“btn btn-primary” @onclick=“CallJSFunctionFromScript”>Call JS function from script</button>
</div>
@code{
private async void CallJSFunctionFromCSWithModule()
{
await exampleJsWithModule.Prompt("Hello, this does not work!");
}
private async void CallJSFunctionFromCSWithJSruntime()
{
await exampleJsRunTime.Prompt("Hello, this does not work!");
}
private async void CallJSFunctionFromScript()
{
await js.InvokeAsync<string>("showPromptFromJS", "Hello, this work!");
}
}
Only CallJSFunctionFromScript works. CallJSFunctionFromCSWithJSruntime and CallJSFunctionFromCSWithModule failed. I have called in MauiProgram.cs:
builder.Services.AddSingleton<ExampleJsInterop>();
builder.Services.AddSingleton<ExampleJsInteropWithJSRunTime>();
and I also have in index.html:
<script src=“./_content/RazorClassLibrary/exampleJsInterop.js”></script>
<script src=“./_content/RazorClassLibrary/JsInterop.js”></script>
However If I create a blazor WebAssembly app not a Blazor Maui app CallJSFunctionFromScript and CallJSFunctionFromCSWithJSruntime work but not CallJSFunctionFromCSWithModule . Why CallJSFunctionFromCSWithJSruntime and CallJSFunctionFromCSWithModule fail in Blazor Maui? and why CallJSFunctionFromCSWithJSruntime works in Blazor WebAssembly app and not in Blazor Maui? The error I get is:
System.NullReferenceException
HResult = 0x80004003
Message=Object reference not set to an instance of an object.
Source=Microsoft.AspNetCore.Components.WebView
StackTrace:
at Microsoft.AspNetCore.Components.WebView.Services.WebViewJSRuntime.BeginInvokeJS(Int64 taskId, String identifier, String argsJson, JSCallResultType resultType, Int64 targetInstanceId)
at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, CancellationToken cancellationToken, Object[] args)
at Microsoft.JSInterop.JSRuntime.<InvokeAsync>d__161.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Threading.Tasks.ValueTask1.get_Result()
at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
at RazorClassLibrary.ExampleJsInteropWithJSRunTime.<Prompt>d__2.MoveNext() in C:\Project\MauiBlazorApp2\RazorClassLibrary\ExampleJsInterop.cs:line 24
This exception was originally thrown at this call stack:
[External Code]
RazorClassLibrary.ExampleJsInteropWithJSRunTime.Prompt(string) in ExampleJsInterop.cs
Thank you
Update: Appently if I use builder.Services.AddScoped(); instead of builder.Services.AddSingleton(); CallJSFunctionFromCSWithJSruntime works. Why the Blazor App works with Singleton and the Maui Blaxor requires Scoped? Also the call of javascript using the default generated code, using module+import js file fails with either scoped or singleton?
Upvotes: 9
Views: 2524
Reputation: 349
To call js from blazor hybrid application in current version(rc2).
you need to replace AddSingleton
to AddScoped
Upvotes: 6