Search code examples
c#asp.net-coreblazorblazor-client-sideblazor-webassembly

Unable to invoke javascript function from blazor component


I'm trying to check if my blazor web assembly app is opened on mobile or not. For that,

I created a wwwroot/script.js file and added code:

function isDevice() {
   return /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini|mobile/i.test(navigator.userAgent);
}

Added reference in index.html

And then in my component:

@inject IJSRuntime JSRunTime
@code {
private string isDevice { get; set; }
private static bool mobile { get; set; }

protected async override Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        mobile = await JSRuntime.InvokeAsync<bool>("isDevice");
        isDevice = mobile ? "Mobile" : "Desktop";
    }
    await base.OnAfterRenderAsync(firstRender);
}
}

I'm getting an error on compile time that:

No overload for method 'InvokeAsync' takes 1 arguments

Please check this image as well.

After checking the docs: https://learn.microsoft.com/en-us/dotnet/api/microsoft.jsinterop.jsruntime.invokeasync?view=aspnetcore-5.0#Microsoft_JSInterop_JSRuntime_InvokeAsync__1_System_String_System_Object___

I changed the code to have second parameter like this:

mobile = await JSRuntime.InvokeAsync<bool>("isDevice", new object[] { });

Now the error is:

An object reference is required for the non-static field, method, or property 'JSRuntime.InvokeAsync(string, object[])'

second error


Solution

  • @inject IJSRuntime JSRunTime

    The issue is related to the above line. If using the above injected name (JSRunTime), in the code block, if we hover the JSRunTime, we can see it is an instance of Microsoft.JSInterop.JSRuntime, instead of the injected object.

    enter image description here

    To solve this issue, try to change the injected object name, like this:

     @inject IJSRuntime JS
    

    Then, you could use the injected object as below:

            @inject IJSRuntime JS
            <p>
                <button @onclick=ShowConfirm>Confirm popup</button>
            </p>
            <p>
                <button @onclick=ShowPrompt>Prompt popup</button>
            </p>
    
            @code { 
                private string Result;
                private async Task ShowConfirm()
                {
                    bool confirmed = await JS.InvokeAsync<bool>("confirm", "Are you sure?");
                    Result = confirmed ? "You clicked OK" : "You clicked Cancel";
                    Console.WriteLine(Result);
                }
    
                private async Task ShowPrompt()
                {
                    string name = await JS.InvokeAsync<string>("prompt", "What is your name?");
                    Result = "Your name is: " + name;
                    Console.WriteLine(Result);
                }
    
            }
    

    The result like this:

    enter image description here

    Reference:

    Call JavaScript functions from .NET methods in ASP.NET Core Blazor