Unable to invoke javascript function from blazor component
Asked Answered
P

2

5

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

Pigment answered 23/11, 2020 at 14:14 Comment(7)
Yeah it takes two arguments... look at docs: learn.microsoft.com/en-us/dotnet/api/…Trove
try JSRuntime.InvokeAsync<bool>("isDevice", new []{});Trove
@Trove I changed it to JSRuntime.InvokeAsync<bool>("isDevice", new object[] { }); but now the error is: An object reference is required for the non-static field, method, or property 'JSRuntime.InvokeAsync<bool>(string, object[])'Pigment
the second paramter is object[]Pigment
You must have removed your @inject IJSRuntime JSRunTime line... You should have got this error even before the change otherwiseTrove
Ah its casing - your inject has JSRunTime while your code has JSRuntime - Notice the lowercase vs capital T for Time/timeTrove
@Milney, thank you for pointing me in this direction. I wasn't missing the line but I had a typo in the name that I was using.Pigment
D
12

@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

Distributee answered 24/11, 2020 at 6:14 Comment(0)
A
-3

C# Code:

[Inject]
IJSRuntime JS { get; set; }

 private async Task Delete()
 {
     if (!await JS.InvokeAsync<bool>("confirm", $"Are you sure you want to delete?"))
     {
         return;
     }
 }
Acoustic answered 26/2 at 14:52 Comment(1)
Please elaborate how your code fixes the issue from the question.Bathyal

© 2022 - 2024 — McMap. All rights reserved.