JavaScript Interop in Blazor
This document covers how to call JavaScript functions from .NET code and .NET methods from JavaScript code in Blazor applications.
Understanding JS Interop
Blazor allows you to seamlessly integrate with existing JavaScript code. This is crucial for leveraging browser APIs, using third-party JavaScript libraries, or when you need to perform DOM manipulations that are more naturally handled in JavaScript.
Calling JavaScript from .NET
You can invoke JavaScript functions from your Blazor components using the IJSRuntime
service. This service is available via dependency injection.
Example: Invoking a simple JavaScript function
First, ensure you have a JavaScript function defined in your wwwroot/index.html
or an included JavaScript file:
function showMessage(message) {
alert(message);
}
In your Blazor component (e.g., a .razor
file), inject IJSRuntime
and call the JavaScript function:
[Inject]
IJSRuntime JS { get; set; }
async Task CallJavaScript()
{
await JS.InvokeVoidAsync("showMessage", "Hello from Blazor!");
}
The InvokeVoidAsync
method is used when the JavaScript function doesn't return a value. If it returns a value, use InvokeAsync<T>
, where T
is the expected return type.
Example: Invoking a JavaScript function that returns a value
JavaScript function:
function addNumbers(a, b) {
return a + b;
}
Blazor component:
[Inject]
IJSRuntime JS { get; set; }
async Task GetSum()
{
int result = await JS.InvokeAsync<int>("addNumbers", 5, 7);
Console.WriteLine($"The sum is: {result}"); // Output: The sum is: 12
}
Calling .NET Methods from JavaScript
To call .NET methods from JavaScript, you need to use the DotNetObjectReference
. This creates a reference to a .NET object that can be passed to JavaScript.
Example: Creating a DotNetObjectReference
In your Blazor component:
@implements IDisposable
// ... other component code
private DotNetObjectReference<MyComponent> objRef;
protected override void OnInitialized()
{
objRef = DotNetObjectReference.Create(this);
}
[JSInvokable]
public void SayHelloFromDotNet(string name)
{
Console.WriteLine($"Hello, {name} from .NET!");
}
public void Dispose()
{
objRef?.Dispose();
}
Now, you need to pass this reference to JavaScript. This is often done when initializing your JavaScript code or when calling a JavaScript function that expects the .NET object reference.
JavaScript code (e.g., in wwwroot/index.html
or a script file):
// Assume 'componentReference' is passed from Blazor
// Example: window.myBlazorComponentRef = componentReference;
function callDotNetMethod(componentReference, name) {
if (componentReference) {
componentReference.invokeMethodAsync("SayHelloFromDotNet", name);
}
}
In your Blazor component, you would invoke this JavaScript function:
[Inject]
IJSRuntime JS { get; set; }
async Task CallDotNetFromJs()
{
// This assumes 'window.myBlazorComponentRef' is set in JS to the DotNetObjectReference
await JS.InvokeVoidAsync("callDotNetMethod", objRef, "JavaScript");
}
Alternatively, you can pass the DotNetObjectReference
directly when needed:
[Inject]
IJSRuntime JS { get; set; }
async Task CallDotNetDirectly()
{
// This passes the reference directly to a JS function that expects it
await JS.InvokeVoidAsync("someJavaScriptFunctionThatAcceptsDotNetRef", objRef);
}
Managing the Lifespan of DotNetObjectReference
It's crucial to dispose of DotNetObjectReference
instances when they are no longer needed to prevent memory leaks. Implement the IDisposable
interface in your component and call objRef?.Dispose()
in the Dispose()
method.
Common Use Cases
- Integrating charting libraries (e.g., Chart.js, D3.js).
- Using browser APIs like Geolocation or LocalStorage.
- Implementing complex UI interactions not covered by Blazor's declarative model.
- Calling legacy JavaScript code.
Performance Considerations
Excessive or synchronous JS Interop calls can impact performance. Consider batching calls where possible and minimizing the number of round trips between .NET and JavaScript.
Conclusion
JavaScript Interop is a powerful feature that extends the capabilities of Blazor. By understanding how to call between .NET and JavaScript, you can build rich and interactive web applications.