Aspnetcore: Blazor: Calling Javasscript Interop on Program.cs

Created on 3 Jun 2019  路  5Comments  路  Source: dotnet/aspnetcore

Hello,

I need to make a Javascript Interop call on the Program.cs. Please, check my code below:

public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateHostBuilder(args).Build();
        using (var scope = host.Services.CreateScope())
        {
            var js = scope.ServiceProvider.GetRequiredService<IJSRuntime>();
            var lang = js.InvokeAsync<string>("myJsFunctions.browserLanguage").Result;
            CultureInfo.DefaultThreadCurrentCulture = new CultureInfo(lang);                
        }
        host.Run();
    }

    public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) =>
        BlazorWebAssemblyHost.CreateDefaultBuilder()
            .UseBlazorStartup<Startup>();
}

I've tried all the possible ways to make that async call, but in all the cases the application is not started on the browser, and it freezes on the loading... page.

Am I doing something wrong? As you can see, I need to catch the browser language before the application is loaded.

Thanks!

area-blazor question

All 5 comments

Wouldn't it be better on the init of your main page?

There's no guarantee that JS interop will be ready before the Blazor application is started up. You will need to move JS interop calls into a later place. For example, in your Startup class:

public void Configure(IComponentsApplicationBuilder app, IJSRuntime jSRuntime)
{
    app.AddComponent<App>("app");

    _ = jSRuntime.InvokeAsync<object>("alert", "Hello, world!");
}

As you can see, I need to catch the browser language before the application is loaded.

If you could clarify why you think you have to do it in Program.cs and not in a regular component (or in Startup.cs if you really want), that would help us to provide better advice.

I'm guessing it's because you want to know the language synchronously. If my guess is correct, you can do it like this in Startup.cs:

public void Configure(IComponentsApplicationBuilder app, IJSRuntime jSRuntime)
{
    var language = ((IJSInProcessRuntime)jSRuntime).Invoke<string>("getBrowserLanguage");
    Console.WriteLine("Your language is: " + language);

    app.AddComponent<App>("app");
}

... and the following JS code in index.html:

<script>
    function getBrowserLanguage() {
        return navigator.language;
    }
</script>

Alternatively you could issue a similar interop call from any of your components.

Thanks a lot! That works great, and I've learned two new things:

  1. I can inject services on the Startup.Configure Method
  2. I can make synchonous JSInterop calls

Sorry if this is not the correct channel for this kind of question. All the answers I found on the web lead me to solve this on the Program.cs, with an async call.

Thank you for your help!

Was this page helpful?
0 / 5 - 0 ratings