Blazor JS Interop: Make Your C# Talk to JavaScript!

Blazor JS Interop Demystified: Make Your C# Talk to JavaScript!

Make Your C# Talk to JavaScript!

Ever wished your Blazor application could do cool things that only JavaScript seems to handle easily, like popping up a classic browser alert or directly manipulating parts of your webpage? Well, you're in luck! Blazor's JavaScript Interop (often shortened to JS Interop) is exactly what you need.

Think of JS Interop as a special translator or a walkie-talkie that allows your C# code (the smart "brain" of your Blazor app) to communicate directly with JavaScript (the "action manager" for your webpage's looks and immediate browser interactions).

In this tutorial, we'll build a simple Blazor component that demonstrates how your C# code can:

  • Call a JavaScript function to show an alert.
  • Call a JavaScript function to ask a question and get the answer back.
  • Call a JavaScript function to update text on your page.

Let's dive in!

Prerequisites

  • Basic understanding of Blazor and C#.
  • A Blazor project (either Blazor Server or Blazor WebAssembly).

Step 1: Create Your JavaScript File

First, we need to create the JavaScript functions that our Blazor application will "call."

  1. Inside your Blazor project, navigate to the wwwroot folder.
  2. Inside wwwroot, you'll likely have a js folder (if not, create one).
  3. Create a new JavaScript file inside the js folder, let's call it app.js.
  4. Now, paste the following JavaScript code into app.js:
// wwwroot/js/app.js

// Function 1: Shows a simple alert pop-up
function showalert() {
    alert("Hello world!, I am a JS function.");
}

// Function 2: Shows a prompt, asks a question, and returns the user's answer
function showprompt(question) {
    return prompt(question);
}

// Function 3: Finds an HTML element by its ID and changes its displayed text
function setElementTextById(id, text) {
    document.getElementById(id).innerText = text;
}

Explanation of the JavaScript code:

  • showalert(): This is a very straightforward function. When called, it simply displays a standard browser alert box with the message "Hello world!, I am a JS function."
  • showprompt(question): This function takes one piece of information (question). It then uses the browser's prompt() feature to display a question to the user. Whatever the user types into the prompt box is then returned by this function.
  • setElementTextById(id, text): This function takes two pieces of information: an id (which will match an ID on an HTML element) and text. It then finds that specific HTML element on the page using its ID and changes the text inside it to the text you provided.

Step 2: Reference Your JavaScript File

For your Blazor application to know about these new JavaScript functions, you need to tell it where to find app.js.

  • For Blazor WebAssembly projects: Open wwwroot/index.html.
  • For Blazor Server projects: Open Pages/_Host.cshtml.

Find the closing </body> tag and add the following line just before it:

<script src="/js/app.js"></script>

This line tells your web page to load your app.js file, making its functions available for use.

Step 3: Create Your Blazor Component (Interop.razor)

Now, let's create the Blazor component that will "talk" to our JavaScript functions.

  • In your Pages folder, create a new Razor Component file named Interop.razor.
  • Paste the following code into Interop.razor:
@page "/interop" // This makes the component accessible at the /interop URL
@inject IJSRuntime JSRuntime // This is our "walkie-talkie" to JavaScript

<h3>JS Interop Demo</h3>

<p>Let's make our C# talk to JavaScript!</p>

<hr />

<h3>1. Create a New Alert</h3>
<button class="btn btn-success" @onclick="ShowAlert">
    Show JS Alert
</button>

<hr />
<br />

<h3>2. Q&A Time! (C# asks, JS prompts, C# displays)</h3>
<p>Enter a question for JavaScript to ask you:</p>
<input @bind="Question" class="form-control" placeholder="E.g., What is your favorite color?" />
<button class="btn btn-info mt-2" @onclick="AskMe">
    Ask Me!
</button>

<div class="mt-3">
    <strong>Here is the answer from JavaScript:</strong> <span id="ans" class="badge bg-secondary p-2"></span>
</div>

@code {
    // A C# variable to hold the question we want to ask
    string Question = string.Empty;

    // This method is called when the "Show JS Alert" button is clicked
    async Task ShowAlert()
    {
        // Calling our JavaScript function 'showalert'
        // JSRuntime.InvokeVoidAsync means: "Call this JS function, and I don't expect anything back."
        await JSRuntime.InvokeVoidAsync("showalert");
    }

    // This method is called when the "Ask Me!" button is clicked
    async Task AskMe()
    {
        // Calling our JavaScript function 'showprompt' and passing our C# 'Question' variable to it.
        // InvokeAsync<string> means: "Call this JS function, and I expect a 'string' (text) back."
        var response = await JSRuntime.InvokeAsync<string>("showprompt", Question);

        // Now that we have the response from JavaScript, let's display it on our page.
        // We're calling another JS function 'setElementTextById' to update the <span> with id="ans".
        // Again, InvokeVoidAsync because we're just telling JS to do something, not get a return.
        await JSRuntime.InvokeVoidAsync("setElementTextById", "ans", response);
    }
}

Explanation of the Blazor Component code:

  • @page "/interop": This line sets the URL for this component. You can access it in your browser by going to /interop.
  • @inject IJSRuntime JSRuntime: This is crucial! This line injects the IJSRuntime service into our component. Remember, IJSRuntime is our "walkie-talkie" for communicating with JavaScript. We're giving it a name, JSRuntime, so we can use it easily in our C# code.
  • HTML Elements:
    • We have a button that will trigger our ShowAlert method.
    • An input field where you type your question.
    • Another button to trigger the AskMe method.
    • A <div> containing a <span> with id="ans". This is where the answer from JavaScript will be displayed. Notice the id="ans" – this is how our JavaScript function setElementTextById will find this specific element!
  • @code { ... } block (C# Logic):
    • string Question = string.Empty;: A simple variable to hold the text from our input field.
    • async Task ShowAlert():
      • await JSRuntime.InvokeVoidAsync("showalert"); This is the magic! We're using our JSRuntime (the walkie-talkie) to tell JavaScript to execute a function named "showalert". InvokeVoidAsync means we're just telling JavaScript to do something, and we don't expect any information back.
    • async Task AskMe():
      • var response = await JSRuntime.InvokeAsync<string>("showprompt", Question);: Here, we're calling the JavaScript function "showprompt". Notice InvokeAsync<string> – this means we do expect something back, specifically a string (text). We also pass our C# Question variable to the JavaScript function as an argument. The response variable will then hold whatever the user typed into the prompt box.
      • await JSRuntime.InvokeVoidAsync("setElementTextById", "ans", response);: Once we get the response from JavaScript, we use JSRuntime again to call another JavaScript function, "setElementTextById". We pass it two pieces of information: "ans" (the ID of our <span> element) and the response text we just received. This makes JavaScript update the text on our page!

Step 4: Run Your Application!

  • Save all your files and run your Blazor application.
  • Navigate to /interop in your browser (e.g., https://localhost:7001/interop).
  • Click the "Show JS Alert" button, and you should see a classic browser alert pop up.
  • Type a question into the input field (e.g., "What is 2 + 2?").
  • Click the "Ask Me!" button. A browser prompt will appear with your question. Type an answer and press Enter.
  • You'll see the answer you typed immediately appear next to "Here is the answer:" on your Blazor page.

How It All Works Together (The Flow):

  • You click a Blazor Button: This triggers a C# method in your @code block (e.g., ShowAlert or AskMe).
  • C# Uses the "Walkie-Talkie": Inside the C# method, you use JSRuntime.InvokeVoidAsync or JSRuntime.InvokeAsync to send a message to JavaScript. You tell it the name of the JavaScript function to run and any data to pass.
  • JavaScript Does Its Job: The JavaScript function (showalert, showprompt, setElementTextById) then executes in the browser. It can interact directly with the browser's features or the HTML elements on the page.
  • JavaScript (Optionally) Replies: If you used InvokeAsync<T>, the JavaScript function will send its result (like the user's answer from prompt) back to your C# code.
  • C# Continues: Your C# code receives the reply (if any) and can then use that information to update variables, perform more logic, or even call another JavaScript function to update the UI, as we did with setElementTextById.

Conclusion

Congratulations! You've successfully implemented Blazor JS Interop. You've seen how powerful this feature is for bridging the gap between your C# backend logic and the dynamic, client-side capabilities of JavaScript. Whether it's integrating a complex JS library, accessing specific browser APIs, or just simple UI manipulations, JS Interop opens up a world of possibilities for your Blazor applications.

Keep experimenting, and happy coding!

Comments

Popular posts from this blog

Blazor: Building Web Apps with C# - Introduction

Blazor WebAssembly Hosted App Tutorial: Envelope Tracker System

Securing MVC-based Applications Using Blazor