Reputation: 2200
I try to call a JS function. The JS script is provided by a third party.
In simple HTML/JS, I can write:
<html>
<head>
<script src="myscriptA.js"></script>
<script src="myscriptB.js"></script>
</head>
<body>
<div id="foo"></div>
<div id="bar"></div>
<script>
var viewer = new foo.Viewer('foo', /*other params*/);
viewer.function1().then(() => { /*ommited code*/ }).catch((error) => { console.log(error)});
document.getElementById('bar').addEventListener('click', event => {
var b1 = new B('bar', /*params*/)});
var b2 = new B('foo');
viewer.addB(b1, b2, { click: function(e) { viewer.function2() } });
</script>
</body>
</html>
I want to do the same thing with Blazor. For the moment, I can reach the myscriptA.js
file with my component:
Page3.razor
@page "/Page3"
@inject IJSRuntime JS
@code {
var scriptA = await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./js/myscriptA.js");
var foo = await JSRuntime.InvokeAsync<IJSObjectReference>("new foo.Viewer", scriptA);
// I have try:
var foo = await JSRuntime.InvokeAsync<IJSObjectReference>("new foo.Viewer", "foo", @*other params*@);
var foo = await JSRuntime.InvokeAsync<IJSObjectReference>("foo.Viewer", "foo", @*other params*@);
var foo = await JSRuntime.InvokeAsync<IJSObjectReference>("Viewer", "foo", @*other params*@);
var foo = await JSRuntime.InvokeAsync<IJSObjectReference>("new Viewer", "foo", @*other params*@);
}
For each C# foo variable in my component, my browser's console shows:
blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Could not find 'new foo.Viewer' ('new foo' was undefined).
Error: Could not find 'new foo.Viewer' ('new foo' was undefined).
at https://localhost:5001/_framework/blazor.webassembly.js:1:1287
at Array.forEach (<anonymous>)
at e.findFunction (https://localhost:5001/_framework/blazor.webassembly.js:1:1247)
at b (https://localhost:5001/_framework/blazor.webassembly.js:1:2989)
at https://localhost:5001/_framework/blazor.webassembly.js:1:3935
at new Promise (<anonymous>)
at Object.beginInvokeJSFromDotNet (https://localhost:5001/_framework/blazor.webassembly.js:1:3908)
at Object.w [as invokeJSFromDotNet] (https://localhost:5001/_framework/blazor.webassembly.js:1:64232)
at _mono_wasm_invoke_js_blazor (https://localhost:5001/_framework/dotnet.5.0.4.js:1:190800)
at do_icall (<anonymous>:wasm-function[10596]:0x194e4e)
As written in the comment (Call JavaScript function (from external library) with Blazor), I want to inject myscriptA.js
and myscriptB.js
only in Page3.razor
file and not in another files (Page1
, Page2
, Page4
, ...).
As *.css files for Blazor components, I tried to add a *.js file with the same name as my page:
Project.csproj
Pages
folder
Page1.razor
Page2.razor
Page2.razor.css
<-- seen in a Shared\NavMenu.razor
Page3.razor
Page3.razor.js
I've the same error
Upvotes: 3
Views: 8657
Reputation: 854
You were close!! To load a JS file only where required (e.g., a specific page), you need to implement the IJSObjectReference
interface and utilize the JavaScript module isolation properly.
Razor page:
@inject IJSRuntime JsRuntime
<h1>My Page</h1>
@code{
private IJSObjectReference MyJsModule { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
try
{
// Load the JS Helpers Module
MyJsModule = await JsRuntime.InvokeAsync<IJSObjectReference>("import", "./js/MyScript.js");
}
catch (Exception ex)
{
Logger.LogError($"Failed to load JS module. Error: {ex}");
}
}
}
private async void AddViewer()
{
try
{
await MyJsModule.InvokeVoidAsync("AddViewer", "foo");
}
catch (Exception ex)
{
Logger.LogError($"Failed to execute JS function. Error: {ex}");
}
}
MyScript.js file:
import "./myScriptWithUsefulCodes.min.js";
export function AddViewer(id) {
var viewer = new foo.Viewer(id, /*other params*/);
/* ...Your code... */
}
Upvotes: 11
Reputation: 9830
Couldn't you just load the JavaScript file in your Blazor Page, the same way as the default Blazor example loads the .json
file?
And then 'execute' the contents from that string as JavaScript using the IJSRuntime ?
Upvotes: 0