3

Inside a Blazor component, I want to call a JS method from the HTML onclick event of an anchor tag, thus:

<a onclick="window.LoadImage();" class="@CssClass">@DisplayName</a> 

My JS method is:

window.LoadImage = () => {
    DotNet.invokeMethodAsync('MyProject', 'FireEvent').then();
}

Inside the JS method, I want to fire a C# static method to trigger an event, thus:

[JSInvokable]
public static void FireEvent()
{
   StateEngine.LoadImage(DisplayName, Target);
}
[Parameter]
public string DisplayName { get; set; }
[Parameter]
public string Target { get; set; }

I can't get the JS method to find the C# method. I've tried multiple name configurations for the first parameter, like

MyProject (the assembly name)
MyProject.FolderName.ComponentName
FolderName.ComponentName
ComponentName

to name a few. I've also tried shuffling names through the second parameter.

How is this supposed to work? What am I missing?

P.S. Please disregard the bit about the instance properties in the static method. I've got a workaround for that, but don't want to clutter up the post.

2 Answers 2

1

From the looks of it, you would be better off using the reference JSInterop so you can access the components properties.

Razor

@inject IJSRuntime JS
@implements IDisposable

 <a @onclick=Clicked>Click here</a>

@code
{
  private DotNetObjecctReference ObjRef;

  [JSInvokable]
  public void FireEvent()
  {
     StateEngine.LoadImage(DisplayName, Target);
  }

  private Task Clicked()
  {
    return JS.InvokeVoidAsync("window.LoadImage", ObjRef);
  }

  protected override Task OnInitializedAsync()
  {
    ObjRef = DotNetObjectReference.Create(this);
  }

  void IDisposable.Dispose()
  {
    ObjRef.Dispose();
  }
}

JS

window.LoadImage = (dotNetObject) => {
    dotNetObject.invokeMethod('FireEvent');
}
Sign up to request clarification or add additional context in comments.

4 Comments

If you create a DotNetObjectReference without disposing it, you app will leak memory - blazor-university.com/javascript-interop/…
@PeterMorris Thanks, edited. For anyone reading this, there are multiple ways you could handle the DotNetObjectReference creation. Creating a new object every js call(and disposing inside the JS) is one method. The link in Peter's above post shows another way using a component property and implementing IDisposable.
I revised it slightly. I think it's impolite to dispose of objects you didn't create. I hope you don't mind and will accept my modifications - but I don't mind if you revert them :)
This gave me enough to go on; but then I had the rug pulled out from under me, and this project is on "eternal hold".
0

Your code looks good. May be its unable to find your .Net method. Give it a retry..

JS

window.LoadImage = function () {
DotNet.invokeMethodAsync("MyBlazorProject.UI", "FireEvent").then();}

First Parameter must be AssemblyName of your Blazor component. In my case, it is "MyBlazorProject.UI".
Second Parameter must be method name.

HTML

<a onclick="window.LoadImage()" class="btn btn-primary">Call .Net Method FireEvent</a>

here onclick is JavaScript event, which is good in your case too.

C# Code

[JSInvokable]
public static void FireEvent()
{
    //debugger hits here
    //StateEngine.LoadImage(DisplayName, Target);
}

This is all working for me fine. Debugger gets hit inside FireEvent .Net method after clicking anchor tag.

output

Thanks

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.