Search code examples
javascriptblazorprogressive-web-appsblazor-server-sideblazor-webassembly

How can i invoke a JavaScript function within a Blazor PWA project?


I am trying to use an Progressive Web Application html template within a server side Blazor project of mine.

For the last 4 days I am having great challenges with it, since all the menus and animations of the template, are implemented with JavaScript within a single file custom.js having the following structure.

enter image description here

Within the _Host file, i have placed the appropriate include

<body class="theme-light" data-highlight="highlight-red" data-gradient="body-default">

    <div id="preloader"><div class="spinner-border color-highlight" role="status"></div></div>

    <component type="typeof(App)" render-mode="ServerPrerendered" />

    <component type="typeof(Menu_settings)" render-mode="Static" />

    <script type="text/javascript" src="_framework/blazor.server.js"></script>
    <script type="text/javascript" src="/scripts/bootstrap.min.js"></script>
    <script type="text/javascript" src="/scripts/custom.js"></script>

</body>

What i noticed is that, if i create a razor component (from the template, Menu_Settings) and place it within the _Host file it works as expected, if it is marked as static.

Strange things happen, (actually nothing) if i place the same component within the MainLayout.razor page.

For this reason i tried using the JavaScript Runtime, to make the magic.

@inherits LayoutComponentBase

@inject IJSRuntime JSRuntime

<PageTitle>Hello World</PageTitle>

<div id="page">
    <Footer_bar></Footer_bar>

    <div class="page-content header-clear-medium">
        @Body    
    </div>

    <Menu_settings></Menu_settings>

</div>


@code{

    private IJSObjectReference js { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            try
            {
                    js = await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./scripts/custom.js");
                    await js.InvokeVoidAsync("init_template");
            }
            catch (Exception ex)
            {
                //Logger.LogError($"Failed to load JS module. Error: {ex}");
            }
        }
    }
}

And now i have two issues.

  1. The component still refuses to work (should display a popup menu).
  2. I get the error Could not find 'init_template' ('init_template' was undefined). when InvokeAsync is called.

I also tried editing the custom.js file like so, with the same error..

enter image description here

Any thoughts please?


Solution

  • The export keyword did the trick.

    export function init_template(){
    
    }