2

I am wondering is it possible to update C# value in Blazor using Javascript

For example

<input type="text" @bind="TestValue" >
<input type="button" value="Change value" onclick="ChangeValueFromJs()" >

@code
{
public string TestValue {get;set;} = "init value";
}

js

function ChangeValueFromJs()
{

}

Is there a way to update TestValue and successfully bind it to text input using js ChangeValueFromJs?

I tried doing this, but it didn't seem to work

function ChangeValueFromJs()
{
     DotNet.invokeMethodAsync("BlazorApp", "invokeFromJS", "ChangeValue");
}

@code
{
    [JSInvokable("invokeFromJS")]
    public static Task ChangeValue()
    {
          TestValue = "New value";
          return null;
    }
}
5
  • If you are not getting any errors, then most likely is that the value is being updated, but you need a call to InvokeAsync(StateHasChanged) inside ChangeValue() to let Blazor know something has changed and it needs to re-render. Commented Nov 11, 2019 at 15:29
  • I cannot call InvokeAsync(StateHasChanged) inside a static method Commented Nov 11, 2019 at 19:23
  • of course you are right, my mistake not reading it correctly. you would need to change your interop to call an instance method which means you would have to pass a dotnet instance to JS initially, which is messy. I prefer to keep things simple - in your javascript, set the value on the input and then use dispatchEvent to raise the change event on the input and Blazor will update the TestValue through binding Commented Nov 11, 2019 at 23:09
  • Could you provide me an example on how to use dispatchEvent in this case Commented Nov 12, 2019 at 7:18
  • In its simplest form without any error handling, var el=document.getElementById('xyz123'); el.value = 'test value'; el.dispatchEvent(new Event('change')); where xyz123 is the id of your input Commented Nov 13, 2019 at 7:20

2 Answers 2

7

I tried doing this, but it didn't seem to work

You're almost there. In order to invoke an instance method, you need to pass the instance reference to Javascript.

How-to

Wrap the onclick="ChangeValueFromJs()" with a C# delegate that will pass this component as a reference to js:

<input type="button" value="Change value" 
    onclick="ChangeValueFromJs()"
    @onclick='async (e) => await jsRuntime.InvokeAsync("ChangeValueFromJs", DotNetObjectReference.Create(this))' 
/gt;

And then change the js to invoke the instance method in following way:

function ChangeValueFromJs(wrapper)
{
    return wrapper.invokeMethodAsync("invokeFromJS")
        .then(_=>{
            console.log('state has changed');
        });
}

Finally, don't forget to add a StateHasChanged(); to notify the component

[JSInvokable("invokeFromJS")]
public Task ChangeValue()
{
    TestValue = "New value";
    StateHasChanged(); 
    return Task.CompletedTask;
}

Demo

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

0

You can call Blazor Component method from JS following these steps:

Here is what I did to load new values in my component listPages by using my component method loadListPagesAsync from JS onScroll event.

1- create a reference to your component in JS, I use initdotNetListPageHelperObj function to make a reference to my dotNetListPageHelper JS:

var dotNetListPageHelperObj;   
function initdotNetListPageHelperObj(dotNetListPageHelper){
    dotNetListPageHelperObj = dotNetListPageHelper;
};

2- I call this method when I initialise the component in Blazor:

Blazor code of my component ListPages:

private DotNetObjectReference<ListPages>? dotNetListPageHelper;

protected override async Task OnInitializedAsync()
 {
   dotNetListPageHelper = DotNetObjectReference.Create(this);
JS.InvokeVoidAsync("initdotNetListPageHelperObj", dotNetListPageHelper);
}
public void Dispose()
{
  dotNetListPageHelper?.Dispose();
}

3- make my function Invokable

Blazor code of my component ListPages:

[JSInvokable]
public void loadListPagesAsync(string pageNumIndex)
{
  loadListPages(Int32.Parse( pageNumIndex));
}

4- JS: I call my method by using dotNetListPageHelperObj and I pass a parameter lastPageVisible:

dotNetListPageHelperObj.invokeMethodAsync('loadListPagesAsync', lastPageVisible);

Using this method I can update my Blazor component ListPages and invoke loadListPagesAsync to load new pages related to lastPageVisible

I hope that this will help someone.

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.