user3468621
user3468621

Reputation: 357

How to return data from event call back to JS interop method in Blazor

Am wrapping some existing JS plugins to blazor components. when doing so, i faced below issue. i have a callback method, which has triggered from JS to blazor using dotnet reference -> invokeMethodAsync

this.dotnet.invokeMethodAsync("Trigger", this.eventName, '');

it's perfectly triggers the JSinvokable method. but here, i need to return the data from blazor source to JS function handler where it has been raised.

Instead invokeMethodAsync, tried invokeMethod, getting the below error

https://github.com/aspnet/Extensions/blob/master/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts#L65

whether it is possible to return data from event call back to JS function from where it has been raised as synchronous action?

Edited:

C# side code

public class ExampleJsInterop
{
    private readonly IJSRuntime _jsRuntime;

    public ExampleJsInterop(IJSRuntime jsRuntime)
    {
        _jsRuntime = jsRuntime;
    }

    public object CallHelloHelperSayHello(string name)
    {
        // sayHello is implemented in wwwroot/exampleJsInterop.js
        return _jsRuntime.InvokeAsync<object>(
            "exampleJsFunctions.sayHello",
            new DotNetObjectRef(new HelloHelper(name)));
    }
}

public class HelloHelper
{
    public HelloHelper(string name)
    {
        Name = name;
    }

    public string Name { get; set; }

    [JSInvokable]
    public string SayHello()
    {
        return $"Hello, {Name}!";
    }
}

JS code:

window.exampleJsFunctions = {
showPrompt: function (text) {
    return prompt(text, 'Type your name here');
},
displayWelcome: function (welcomeMessage) {
    document.getElementById('welcome').innerText = welcomeMessage;
},
returnArrayAsyncJs: function () {
    DotNet.invokeMethodAsync('BlazorSample', 'ReturnArrayAsync')
        .then(data => {
            data.push(4);
            console.log(data);
        });
},
sayHello: function (dotnetHelper) {
    debugger;
    dotnetHelper.invokeMethod('SayHello')
        .then(r => {
            debugger;
            console.log(r);
        });

    console.log('function outside');
}

};

Razor code:

@inject IJSRuntime JSRuntime

<button type="button" class="btn btn-primary" onclick="@TriggerNetInstanceMethod">
    Trigger .NET instance method HelloHelper.SayHello
</button>

@functions {


public void TriggerNetInstanceMethod()
{

    var exampleJsInterop = new ExampleJsInterop(JSRuntime);
    exampleJsInterop.CallHelloHelperSayHello("Blazor");
}
}

Here HelloHelper class -> SayHello method is not triggered from JS to C# side when i particularly mapped via invokeMethod not invokeMethodAsync?

Upvotes: 5

Views: 8601

Answers (2)

user3468621
user3468621

Reputation: 357

Found answer for this question to collect the data back through aync action.

JS Code:

sayHello: async function (dotnetHelper) {

    var promise = dotnetHelper.invokeMethodAsync('SayHello')
        .then(r => {
            debugger;
            console.log(r + "inside");
        });

    var result = await promise; // wait till the promise resolves (*)

    console.log('function outside');
}

in Js, used async function to resolve this issue

Upvotes: 1

enet
enet

Reputation: 45596

It's perfectly triggers the JSinvokable method. but here, i need to return the data from blazor source to JS function handler where it has been raised.

Can I rephrase your statement thus:

The JSinvokable method is called, but I can't return a value to the JS method.

Right ?

You can follow this code:

<button type="button" onclick="exampleJsFunctions.returnArrayAsyncJs()">
    Trigger .NET static method ReturnArrayAsync
</button>

@functions {
    [JSInvokable]
    public static Task<int[]> ReturnArrayAsync()
    {
        return Task.FromResult(new int[] { 1, 2, 3 });
    }
}


And this:




 window.exampleJsFunctions = {
  returnArrayAsyncJs: function () {
    DotNet.invokeMethodAsync('BlazorSample', 'ReturnArrayAsync').then(data => {
      data.push(4);
      console.log(data);
    })
  }
};

Hope this helps...

Upvotes: 4

Related Questions