DRSJ99
DRSJ99

Reputation: 91

Blazor Maui issue when calling JavaScript method from Component class library. Same code works with Blazor WebAssembly app

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

Answers (1)

Sajjad Arash
Sajjad Arash

Reputation: 349

To call js from blazor hybrid application in current version(rc2). you need to replace AddSingleton to AddScoped

Upvotes: 6

Related Questions