Blazor JavaScript Interoperability
Blazor JavaScript Interoperability

Blazor Apps – JavaScript Interoperability Demo

A Blazor app can invoke JavaScript (JS) functions from .NET methods and .NET methods from JS functions. These scenarios are called JavaScript interoperability (JS interop).

In this article, we are going to have a look at how to achieve it.

Prerequisites

Let’s create a Blazor WebAssembly Standalone app. Then add a Razor component, Demo.razor to it, under Pages folder. Then modify the NavMenu.razor file from Shared folder and add a side navigation item to allow navigation to this new page.

Once this is done, let’s change the index.html file from wwwroot folder and add the script given below inside the body of the HTML document.

Calling JavaScript from .NET

IJSRuntime is registered by the Blazor framework. To call into JS from .NET, inject the IJSRuntime abstraction in the component (or any C# class from where you want to call JavaScript methods).

This abstraction provides three APIs:

These methods take following parameters:

  • A string, specifying the identifier of the function, relative to the global scope. For example, if we declare a JavaScript method window.customers.getCustomers, then for calling method from the IJSRuntime abstraction, we need to pass customers.getCustomers.
  • The .NET Code can also pass any number of parameters to the JavaScript functions. The parameters must be JSON serializable and they should be passed as Object[].
  • The API also takes a CancellationToken as parameter.
  • The TValue return type must also be JSON serializable. TValue should match the .NET type that best maps to the JSON type returned.

As per documentation, if a Blazor app has pre-rendering enabled, then calling JavaScript is not possible during pre-rendering.

The code snippet given below shows 2 different JavaScript functions. One function is just to show an Alert, so it does not return any value. The other function takes to values and returns the addition. We already have added this in the index.html file

Then, let’s modify the Demo.razor component as shown in the code snippet given below.

  • As shown in the code, inject the IJSRuntime abstraction in the component by using @inject directive
  • Then, InvokeVoidAsync should be used when JavaScript function does not return any value. We have used this to show an alert from JavaScript function. JavaScript accepts product name and price as parameters.
  • And, InvokeAsync<T> for calling JavaScript function, where .NET needs to know the returned value from the JavaScript function. We have used this to call a method, add, from JavaScript. This method accepts two integers as parameter and returns the addition of those two numbers.

When the code is executed, we can try clicking both the buttons to ensure that JavaScript is getting called and appropriate results are shown.

Blazor Apps – Calling JavaScript from .NET

Calling .NET Code from JavaScript

In previous section, we have seen how to call a JavaScript function from .NET code. Now, let’s check how the .NET method can be invoked from JavaScript code. This section is divided into two parts – invoking static methods and invoking instance method.

For invoking any public C# method from JavaScript, the method must be decorated with [JSInvokable] attribute. This parameter also takes a string as optional parameter. If that value is passed, then it becomes the identifier of the C# method, which should be used by JavaScript while invoking the C# method. If no parameter value is passed, then C# method name should be used by JavaScript code.

Invoke Static C# Methods From JavaScript

Invoking static methods is easy. Just place the attribute on the static method. Then in JavaScript use DotNet.invokeMethodAsync, which accepts assembly name, method name and the parameters.

Now, let’s go to our Demo.razor component. There, let’s add a public static method, Multiply, which takes two integers as parameters. It performs multiplication and returns the result. Decorate this method with [JSInvokable] attribute. Then in the markup, we can add a simple button which calls a JavaScript function, callDotNetMethod, when it is clicked.

This piece of code is given in the snippet below.

Now, let’s add a simple script, callDotNetMethod, in index.html file. It is shown in the code snippet given below.

When we execute the code and hit the button, we can see the alert as shown in the snapshot given below. If you do not see this alert, then open the developer tools console and you may see an error explaining what went wrong.

Blazor App – Call Static .NET Method from JavaScript

Invoke Instance C# Methods From JavaScript

Invoking instance members needs more work than invoking static methods. It is because, the JavaScript must know the instance on which instance method should be invoked.

To invoke an instance .NET method from JavaScript (JS):

  • We need to create the .NET instance and then pass it by reference to JavaScript by wrapping the instance in a DotNetObjectReference and calling Create on it.
  • Then, we can invoke a .NET instance method from JS using invokeMethodAsync or invokeMethod (Blazor WebAssembly only) from the passed DotNetObjectReference. The .NET instance can also be passed as an argument when invoking other .NET methods from JS.
  • Then we should dispose of the DotNetObjectReference to avoid any memory leaks.

Once we have the reference to the instance in JavaScript, we do not need to use assembly name. We can call invokeMethodAsync on that reference, and pass the method name and parameters. Here as well, the method must be a public method, decorated with [JSInvokable] attribute.

Now, let’s move to our Demo.razor component. There are two buttons:

  • first button click calls a C# method. This method, PassInstanceByReference, passes the instance to JavaScript by calling a JavaScript function from .NET. This instance would be used by JavaScript to make a call to .NET instance method.
  • second button click calls a JavaScript function, which uses the dotnet object and calls an instance method on it. Note that the .NET instance method must have [JSInvokable] attribute and it must be a public method.

Firstly, let’s have a look at the code in Demo.razor component. For better understanding, I have removed all other code and kept only the code which is relevant for calling instance methods. As you can see in the code given below, the component implements IDisposable, to dispose the DotNetObjectReference to avoid any memory leaks.

Now, let’s move to index.html and add the two JavaScript functions:

  • first function, setDotNetObjectReference, is to set the instance variable in global scope
  • second function, showWelcomeMessage, is responsible for using the global variable and then calling .NET instance member.

When we execute this code, we need to make sure that we click the buttons in appropriate order. First click the button to pass the .NET instance to JavaScript and then call another button to invoke JavaScript which will call .NET instance member.

Blazor App – JavaScript to call .NET instance methods

You can find the complete code on my GitHub repository. I hope you find this information helpful. Let me know your thoughts.

Leave a ReplyCancel reply