From the course: Blazor: Getting Started

Call JavaScript from Blazor - Blazor Tutorial

From the course: Blazor: Getting Started

Start my 1-month free trial

Call JavaScript from Blazor

- [Narrator] Now that Blazor has been around for a couple of years and is not long just experimental, it does have a lot of libraries and plugins that allow for functionality that you would expect in a web app. But in the grand scheme of web app platforms, it's still fairly young. There are a lot of features that have already been written in JavaScript that we can improve our app by taking advantage of. One of those things is the local storage access that we used in the last chapter. That Blazor library is internally calling JavaScript to set browser local storage values. Let's look at how to incorporate some existing JavaScript into our application. I've created a simple animation for a rotating beam with Three.js in JavaScript, and I'd like to use that on the settings page. You'll find that JavaScript file for Three.js and the code for the rotating beam in the exercise files. In the client, in the wwwroot folder, let's create a new folder for JS. Then I'll use the terminal to copy my files over. First, I'll copy from the exercise files folder, three.min.js to my Beam.Client folder in the wwwroot and my new JS folder. Now do the same for animation.js. Now let's reference these files in our index.html. I'll add script tags for each of them. We can't place script tags in component files because script tags can't be updated dynamically when the component loads. All the JS scripts will be loaded when the application is loaded. In the first file that we've added here, three.min.js, is the minified version of a 3D rendering engine library for JavaScript. Find out more about it here at threejs.org. I've written animation.js. Here on line two, you can see the function, loadAnimation, that I've added here. It uses the Three.js library to build our beam. We want to call this loadAnimation method. It takes an elementId, a width and a height so that it knows how to size the animation. We don't need to worry about the details of this library or the animation itself. To call this function, we'll create a new service. I'll name it AnimationService.cs. I know that I want to use the JSInterop, so I'll start with a using statement for that. I'm going to do it asynchronously, so I'll use System.Threading.Tasks as well. We'll put it in the services namespace, and create a field for the JSRuntime. We'll inject the JSRuntime in the constructor. Now let's add a method to load the animation. Since JavaScript invoke returns a ValueTask, we'll have this method do the same. A ValueTask is a special case of the more common Task. It can be returned directly if the method completion is synchronous, but it can also run asynchronously. We'll call it LoadAnimation, and it'll take the elementId, the width and the height. To call JavaScript methods, we'll that JSRuntime. I'm using InvokeVoidAsync since I'm not returning anything from this method. You can use the generic method, InvokeAsync, with a type if you want to return an object from your JavaScript method. The first argument is the identifier. In this case, the method I want to run is animatedBeam.loadAnimation. I'll pass the parameters through. We'll need to register this service to use it, just like we've registered other services. I'll go down to the Program.cs, and add builder.Services.AddSingleton AnimationService. We'll see why I registered this as a singleton in the next video. Now we're ready to call this from our application. I'll click here to save the files I have open, and we'll go to the settings page. The settings page isn't doing much anymore, so let's add some flare to it. We'll start by injecting the AnimationService. I need a div to load the animation in. So I'll create that div and give it an ID that I can pass to JavaScript. It's important to keep elements for JavaScript separate from your other elements you're manipulating with Blazor. If you're modifying elements in JavaScript and Blazor at the same time, Blazor's rendering engine will no longer be able to do the differential updates that it needs to. We'll add a code section since I need to make sure that the element is ready before I act on it with JavaScript. We'll use the lifecycle method, OnAfterRenderAsync. It has a parameter so that we can know if this is the first time the page is being rendered or not. Since we only want to load the animation one time, we'll say if firstRender, await AnimationService.LoadAnimation. We'll give it the ID we entered above, and I'll start with a width of 1000 and a height of 200. We'll format and save, and run the application. When we select the settings page, we got an exception. Let's open the browser tools to check it out. I'll select the console. The page couldn't find the animated beam method on the window. Since our index page may be cached, let's do a full reload. Command+Shift+R on Mac, or Control+F5 on Windows. There's our beam, it looks pretty good. All right, our Beam app now has a little bit more beam.

Contents