It’s awesome we can now use C# in the browser with Blazor. But unfortunately we can’t do everything with it, yet. Currently, WebAssembly isn’t able to directly access the DOM API, which means that Blazor isn’t able to either.

So how do we manage this?… The answer is JavaScript interop.

Part of Blazor is implemented and lives in the JavaScript world. It is though this interface that Blazor is able to manipulate the DOM to render the UI and to hook into various DOM events. It’s also how developers can register and call their own JavaScript functions from C# code.

Calling JavaScript functions from C#

To call a JavaScript function from C# it must be registered on the window object. Let’s look at how we can call the following function from C#. It is just a simple alert which will display whatever message is passed to it.

window.ShowAlert = (message) => {
    alert(message);
}

In order to make this call we need to inject a IJSRuntime into our C# code. In the example below, I’ve setup a basic component which has an input so we can enter a message. And a button which will invoke the JavaScript call.

@inject IJSRuntime jsRuntime

<input type="text" @bind="message" />
<button @onclick="ShowAlert">Show Alert</button>

@code {

    string message = "";

    private async Task ShowAlert()
    {
        await jsRuntime.InvokeAsync<object>("ShowAlert", message);
    }
}

Calling C# methods from JavaScript

What about call into C# from JavaScript? Yes, that is also possible, and necessary. For example, if you are calling an asyncronous JavaScript function you will need it to callback into your code when the operation completes.

In order for a C# method to be called from JavaScript it must be decorated with the [JSInvokable] attribute, for example.

namespace JSInteropExamples
{
    public static class MessageProvider
    {
        [JSInvokable]
        public static Task GetHelloMessage()
        {
            var message = "Hello from C#";
            return Task.FromResult(message);
        }
    }
}

We can then call this from JavaScript using DotNet.invokeMethodAsync in the following way.

window.WriteCSharpMessageToConsole = () => {
    DotNet.invokeMethodAsync('JSInteropExamples', 'GetHelloMessage')
      .then(message => {
        console.log(message);
    });
}

Summary

In this post, we looked at what JavaScript interop is as well as why we need it. We then looked at an example of how to call a JavaScript function from C# using IJSRuntime. Finally, we looked at an example of how to call a static C# method from JavaScript.

JavaScript interop can be a complex aspect of developing with Blazor. I have written an in depth post covering using JavaScript interop with Blazor. I would really recommend giving it a read before getting to stuck in with code.