Search code examples
javascript.netblazorblazor-webassemblyblazor-jsinterop

Calling a non static method using blazor interop from js


Working on a blazor application, it has a method that needs to be called from the JS ! When I try to call the method without static keyword I get this error -

 The assembly 'AssemblyName' does not contain a public invokable method with [JSInvokableAttribute("INIT_COMPLIANCE")].

As soon as I add static it recognizes and loads it fine.

Here's my code in blazor component -

protected override Task OnInitializedAsync()
    {
        jsToDotNetBridgeReference = DotNetObjectReference.Create(this);
        js.InvokeVoidAsync("SetDotNetReference", jsToDotNetBridgeReference);
        return base.OnInitializedAsync();
    }


[JSInvokableAttribute("INIT_COMPLIANCE")]
public async void InitComplianceComponent(string token)
{
    id_token = token;
    Console.WriteLine(token);
    await GetData();
}

JS -

 self.addNewCompliance = function () {
        const url = someurl;
        var resource = window.authContext.getResourceForEndpoint(url);
        window.authContext.acquireToken(resource, function (error, token) {
            // Handle ADAL Error
            if (error || !token) {
                console.log('ADAL Error Occurred: ' + error);
                return;
            } else {
                Blazor.start().then(() => {
                    window.InitComplianceComponent(window.DotNet, token); 
                })
                //window.InitComplianceComponent(window.DotNet, token);
            }
        });
    }

BlazorInterop.js

 InitComplianceComponent = function (dotnetObj, token) {
        dotnetObj.invokeMethod("AssemblyName", "INIT_COMPLIANCE", token);
        
    }

I do not want to use static keyword as the GetData is non-static method and I cannot call it from the static method.

Where am I wrong here.


Solution

  • you can do like this:

    protected override async Task OnInitializedAsync()
    {
        await JSRuntime.InvokeVoidAsync("yourJsFunctionName", 
        DotNetObjectReference.Create(this), nameof(MethodToInvokeFromJs));
    }
    
    [JSInvokable]
    public void MethodToInvokeFromJs()
    {
        //your code
        StateHasChanged();
    }
    

    and your js code will look like this:

    function yourJsFunctionName(instance, callback) {
        instance.invokeMethodAsync(callback);
    }