Blazor pass a javascript object as an argument for IJSRuntime

Viewed 3013

I want to pass a javascript object that is already existed in a javascript file as a parameter to InvokeVoidAsync method :

myJs.js :

var myObject= {a:1,b:2};

MyComponent.razor :

@inject IJSRuntime js

@code {
    private async Task MyMethod()
    {
        await js.InvokeVoidAsync("someJsFunction", /*how to add myObject here? */);
    }
}

How to pass myObject to the someJsFunction function? (Note that the function may also should accept c# objects too)

3 Answers

I finally found the trick, simply use the eval function :

  private async Task MyMethod()
    {
        object data = await js.InvokeAsync<Person>("eval","myObject");
        await js.InvokeVoidAsync("someJsFunction", data );
    } 

in the example below, "someJsFunction" accepts an object of type Person :

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

in my javascript file

var myObject = { name: "Pat", age: 38 }; //a person

//this function provides access to myObject
window.getMyObject = () =>
{
    return myObject;
};

window.someJsFunction = (person) =>
{
    console.log(person);
}

In the component :

@page "/"
@inject IJSRuntime js


<div>
    <button @onclick="MyMethod" >Click</button>
</div>

@code{

    Person Person;

    protected async override Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            //retrieve myOject and assign to the field Person
            Person = await js.InvokeAsync<Person>("getMyObject");
        }
    }

    private async Task MyMethod()
    {
        if(Person != null)

        //pass Person to someJsFunction
        await js.InvokeVoidAsync("someJsFunction", Person);
    }
}

You could define a new JS function

someJsFunctionWithObj(){
    someJsFunction(myObject);
}

Then call that instead...

await js.InvokeVoidAsync("someJsFunctionWithObj");

Or create a JS function that returns the object -> call that from C# to get it -> then pass it back, but that seems quite convoluted.

It sounds like probably you should rethink your design really... Maybe if you explained why you are actually trying to do this we can suggest better idea?

Related