41

With a normal single page razor component in Blazor. I can inject IJSRuntime like this at the top of the page:

@inject IJSRuntime JSRuntime

If I create a code behind .razor.cs file for the component, how do I inject something like IJSRuntime into the code behind file?

LPLN
  • 475
  • 1
  • 6
  • 20
Kyle
  • 32,731
  • 39
  • 134
  • 184

1 Answers1

54

In the code behind razor.cs file, IJSRunTime or others can be injected with the [Inject] attribute

public partial class BillingDashboard
{
    [Inject]
    IJSRuntime JSRuntime { get; set; }

    protected override async Task MyFunction()
    {
         await JSRuntime.InvokeVoidAsync("console.log('test')");
    }
}
JHBonarius
  • 10,824
  • 3
  • 22
  • 41
Kyle
  • 32,731
  • 39
  • 134
  • 184
  • 1
    This method of course may fail as it is residing in the wrong location. Please, move it to the OnAfterRenderAsync method. And provide a parameter in the form "namespace.methodname". No hard feelings! I'll delete this comment after you update your answer... – enet Dec 11 '19 at 18:22
  • 6
    There are valid use cases for calling javascript in `OnInitializedAsync`, like if you only want the JS to run the first time and not on every rerender and are not accessing DOM elements in the component, this discussion is also not particularly relevant to the question of how to inject something in a razor component code behind file. – Kyle Dec 11 '19 at 18:40
  • 1
    I just wanted to ensure that your code, no matter what it is purported to demonstrate, is coded well, not to enter into any kind of arguments. However, JavaScript is not available when pr-rendering, etc., some child components, are not yet created, etc., and OnAfterRenderAsync is the most appropriate place to initialize (only once) JavaScript objects, and to apply new settings, etc. (occurring multiple times). This is exactly why the boolean parameter named firstRender was introduced as of late to OnAfterRenderAsync. – enet Dec 11 '19 at 19:28
  • 3
    Don't forget `using Microsoft.AspNetCore.Components;`! – Joshua Schlichting Oct 15 '20 at 00:17
  • small edit, altough it also could (or should?) just be `protected override Task MyFunction() => JSRuntime.InvokeVoidAsync("console.log('test')");` – JHBonarius Feb 28 '21 at 10:51
  • I'm trying to figure out if there's an obvious enhancement to using the `[Inject]` decoration vs just injecting through the constructor. – Paul Carlton Mar 29 '23 at 19:17
  • @PaulCarlton More concise code is the only advantage I know of. – Kyle Apr 04 '23 at 16:39
  • @Kyle - I figured it out. It's because if you have code behind in a separate class from your blazor razor front end, it must extend ComponentBase and have a parameterless constructor. Obviously you can't inject dependencies through the constructor, hence the `[Inject]` attribute. There might be other reasons, but that's the biggest one I've seen so far. – Paul Carlton Apr 04 '23 at 23:55