I am trying to update my Blazor page on an event generated by js.Js with interop invokes C# code on an event and i need to somehow call this.StateHasChanged in the  c# callback :
JS
window.methods = {
    timeout: null,
    setTimeout: function () {
        timeout = window.setInterval(async function () {
            console.log("From js timeout occured ,sending to .net");
            await DotNet.invokeMethodAsync('[assembly name]', "TimeoutCallback", Date.now().toString());
        }, 2000);
    },
    clearTimeout: function () {
        if (this.timeout == null || this.timeout == undefined) {
            return;
        }
        console.log("Clearing timeout");
        window.clearTimeout(timeout);
    }
}
C#
@inherits StuffBase
@page "/test"
Current value: @val
<button onclick="@(async()=>await StartTimeout())">Start timeout </button>
<button onclick="@(async()=>await ClearTimeout())">Clear timeout</button>
public class StuffBase : BlazorComponent {
        protected static string val { get; set; }
        protected async Task StartTimeout() {
            await JSMethods.SetTimeout();
        }
        [JSInvokable("TimeoutCallback")]  //gets called by js on event !
        public static async Task TimeoutCallback(string data) {
            val = data; 
            Console.WriteLine("From callback ,received:" + data); //gets updated
            await Task.Delay(1000);
           //how can i call this.StateHasChanged
        }
        protected async Task ClearInterval() {
            await JSMethods.ClearInterval();
        }
    }
Interop
public class JSMethods {
        public static async Task SetTimeout() {
            await JSRuntime.Current.InvokeAsync<string>("methods.setTimeout");
        }
        public static async Task ClearTimeout() {
            await JSRuntime.Current.InvokeAsync<string>("methods.clearTimeout");
        }   
    }
As you can see first i call from c# -> setTimeout that in js attaches the timeout with its handler.
What happens is that i manage to get the TimeoutCallback  called from js but and while in console i get my value updated , i somehow need to notify the UI to update itself.
How can i achieve this since all my .NET methods that are called from js have (according to the documentation) to be static ?
I think it would be a nicer option to pass the C# instance down to JS and have your JS call back to that C# instance.
StuffBase.cs
    public class StuffBase : ComponentBase
    {
        protected static string val { get; set; }
        protected async Task StartTimeout()
        {
            await JSRuntime.Current.InvokeAsync<string>("methods.setTimeout", new DotNetObjectRef(this));
        }
        [JSInvokable("TimeoutCallback")]  //gets called by js on event !
        public async Task TimeoutCallback(string data)
        {
            val = data;
            Console.WriteLine("From callback ,received:" + data); //gets updated
            await Task.Delay(1000);
            StateHasChanged();
        }
        protected async Task ClearTimeout()
        {
            await JSMethods.ClearTimeout();
        }
    }
JS
window.methods = {
    timeout: null,
    setTimeout: function (stuffBaseInstance) {
        timeout = window.setInterval(async function () {
            console.log("From js timeout occured ,sending to .net");
            await stuffBaseInstance.invokeMethodAsync('TimeoutCallback', Date.now().toString());
        }, 2000);
    },
    clearTimeout: function () {
        if (this.timeout == null || this.timeout == undefined) {
            return;
        }
        console.log("Clearing timeout");
        window.clearTimeout(timeout);
    }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With