Description
Hi, I have a simple Blazor wasm project where I have javascript invoke / interop's. In a .razor page this works. I have a small illustration project on Github, the page Pages/TestJS.razor invokes a .js function which I print out to the user. I have to capsulate and add that javascript invoke's now to a separate class, so I can standardize and reuse the functions on different pages.
Problem
The new class I want to build in my invoke's is in Classes/JSFunctionHandler_Shared.cs accessing the javascript function in TestEmbed.js. This function I am integrating on the page Pages/TestJSEmbed.razor for test. But now it returns a exception when I initialize the javascript part in the new class.
Blazor page direct js access (works):
@page "/TestJS"
@inject IJSRuntime JsRuntime
<h3>Test JS (in razor component)</h3>
<button @onclick="onTestJS">Test JS</button>
@code {
public async Task onTestJS()
{
await JsRuntime.InvokeAsync<object>("TestJS"); // Test.js
}
}
Blazor page new with js in a class(not wirking):
@page "/TestJSEmbed"
@using Classes
@inject IJSRuntime JsRuntime
<h3>Test JS Embed (interop by class)</h3>
<button @onclick="onTestJSEmbed">Test JS</button>
@code {
JSFunctionHandler JSTest = new JSFunctionHandler();
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
await JSTest.Init();
}
public async Task onTestJSEmbed()
{
await JSTest.TestFunction_JSTestEmbed();
}
}
Class with javascript handling:
using Microsoft.JSInterop;
using Microsoft.AspNetCore.Components;
namespace Classes
{
public partial class JSFunctionHandler
{
[Inject]
public IJSRuntime JSRuntime { get; set; }
private IJSObjectReference _jsModule;
public async Task Init()
{
_jsModule = await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./JS/TestEmbed.js");
}
public async Task TestFunction_JSTestEmbed()
{
await _jsModule.InvokeAsync<object>("JSTestEmbed");
}
}
}
Note: The javascript file I would like to access in the class "JSFunctionHandler" I have not added to the index.html because I am loading it in the init() method. This just because I have not found any other example do this for example over index.html assignment.. This could be changed of course.
A small example project just for illustration of the two scenarios is available in Github
Exception (when opening page TestJSEmbed.razor)
Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] Unhandled exception rendering component: Value cannot be null. (Parameter 'jsRuntime') System.ArgumentNullException: Value cannot be null. (Parameter 'jsRuntime') at Microsoft.JSInterop.JSRuntimeExtensions.InvokeAsync[IJSObjectReference](IJSRuntime jsRuntime, String identifier, Object[] args) at Classes.JSFunctionHandler.Init() in C:\Users\Operator\Documents\GitHub\testdata\BlazorWASM_JSInvoke\ExperimentalTest\Classes\JSFunctionHandler_Shared.cs:line 16 at ExperimentalTest.Pages.TestJSEmbed.OnAfterRenderAsync(Boolean firstRender) in C:\Users\Operator\Documents\GitHub\testdata\BlazorWASM_JSInvoke\ExperimentalTest\Pages\TestJSEmbed.razor:line 16