I have a Maui App targeting Android and Windows. In this app I use scoped JS files for my custom components. All custom components are inheriting from a base class called ComponentBaseExtended which inherits from ComponentBase. in ComponentBaseExtended i have a method trying to load JS modules for the custom component if existing.
This is part of my scoped CS (SwipeItem.razor.cs) where i invoke the method "SwipeRight" not working:
if (swipeDirection == MudBlazor.SwipeDirection.LeftToRight && !_editDrawerOpen)
{
// from default to edit
motionClass = "move-right";
deleteIconClass = "icon-hidden";
editIconClass = "icon-visible";
await JSRuntime.InvokeVoidAsync("SwipeRight");
}
This is my scoped JS (SwipeItem.razor.js):
let isModuleLoaded = false;
export function initModule() {
console.log("initModule - Value of isModuleLoaded:", isModuleLoaded);
isModuleLoaded = true;
}
export function SwipeRight() {
console.log("adjustWidthOnSwipeRight - Value of swipeDistance:");
}
export function moduleLoaded() {
console.log("moduleLoaded - Value of isModuleLoaded:", isModuleLoaded);
return isModuleLoaded;
}
This is how i load the module and execute its functions (ComponentBaseExtended.razor.cs):
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var type = typeof(TComponent);
var namespaceParts = type.Namespace?.Split('.') ?? Array.Empty<string>();
var folderPath = string.Join("/", namespaceParts.Skip(1)); // Skip the root namespace
var componentName = type.Name;
var scriptPath = $"./{folderPath}/{componentName}.razor.js";
try
{
// Load the JS module
var module = await JSRuntime.InvokeAsync<IJSObjectReference>("import", scriptPath);
await module.InvokeVoidAsync("initModule");
var isLoaded = await module.InvokeAsync<bool>("moduleLoaded");
if (!isLoaded)
{ }
else
{
await module.InvokeVoidAsync("SwipeRight");
}
}
catch (JSException jsex)enter code here
{
// Handle the case where the script doesnt exist
Console.WriteLine($"No JS module found for {componentName}, or there was an error in loading it.");
}
}
}
Well on my ComponentBaseExtended i successfully can load the module, after that i successfully execute methods of this module called initModule, SwipeRight and moduleLoaded. I also see the debug lines in Output. But SwipeRight method can not be executed from SwipeItem.razor.cs, I get this error: [chromium] Error: Could not find "adjustWidthOnSwipeRight" ("adjustWidthOnSwipeRight" was undefined).
I guess i am having some issues due to scope of module, which seems to be lost in custom component. How to get rid of this?!
Found my error. It seems that - and correct me if I am wrong - JSRuntime is a scoped service which means its lifecycle scoped to base class where my functions work fine. But in my custom component i do have another scope, so i loose the loaded module. The trick was to load the module in base class and store it in a protected field for usage in my custom component. Instead of this call:
i now call it from my field: