diff --git a/src/Components/test/E2ETest/Tests/InteropTest.cs b/src/Components/test/E2ETest/Tests/InteropTest.cs index bb0e371cb902..b98fb69d72f1 100644 --- a/src/Components/test/E2ETest/Tests/InteropTest.cs +++ b/src/Components/test/E2ETest/Tests/InteropTest.cs @@ -107,6 +107,8 @@ public void CanInvokeInteropMethods() ["invokeNewWithClassConstructorAsync.dataProperty"] = "abraka", ["invokeNewWithClassConstructorAsync.function"] = "6", ["invokeNewWithNonConstructorAsync"] = "Success", + // Function reference tests + ["changeFunctionViaObjectReferenceAsync"] = "42" }; var expectedSyncValues = new Dictionary @@ -171,6 +173,8 @@ public void CanInvokeInteropMethods() ["invokeNewWithClassConstructor.dataProperty"] = "abraka", ["invokeNewWithClassConstructor.function"] = "6", ["invokeNewWithNonConstructor"] = "Success", + // Function reference tests + ["changeFunctionViaObjectReference"] = "42" }; // Include the sync assertions only when running under WebAssembly diff --git a/src/Components/test/testassets/BasicTestApp/DotNetToJSInterop.razor b/src/Components/test/testassets/BasicTestApp/DotNetToJSInterop.razor index 54641d49b69c..b57a78849eda 100644 --- a/src/Components/test/testassets/BasicTestApp/DotNetToJSInterop.razor +++ b/src/Components/test/testassets/BasicTestApp/DotNetToJSInterop.razor @@ -92,6 +92,7 @@
+ @InstanceMessage
@@ -146,13 +147,13 @@ private async Task CreateInstanceByConstructorFunction() { - var dogRef = await JSRuntime.InvokeNewAsync("Dog", ["Igor"]); + var dogRef = await JSRuntime.InvokeNewAsync("Dog", "A dog"); InstanceMessage = await dogRef.InvokeAsync("bark"); } private async Task CreateInstanceByClassConstructor() { - var catRef = await JSRuntime.InvokeNewAsync("Cat", ["Whiskers"]); + var catRef = await JSRuntime.InvokeNewAsync("Cat", "A cat"); InstanceMessage = await catRef.InvokeAsync("meow"); } @@ -166,6 +167,15 @@ await JSRuntime.SetValueAsync("testObject.getOnlyProperty", 123); } + private async Task ChangeInstanceMethodWithFunctionReference() + { + var dogRef = await JSRuntime.InvokeNewAsync("Dog", "A dog"); + var dogFuncRef = await dogRef.GetValueAsync("bark"); + var catRef = await JSRuntime.InvokeNewAsync("Cat", "A cat"); + await catRef.SetValueAsync("meow", dogFuncRef); + InstanceMessage = await catRef.InvokeAsync("meow"); + } + class TestObjectModel { public int Num { get; set; } diff --git a/src/Components/test/testassets/BasicTestApp/InteropComponent.razor b/src/Components/test/testassets/BasicTestApp/InteropComponent.razor index 1009732d9e87..92d845d42571 100644 --- a/src/Components/test/testassets/BasicTestApp/InteropComponent.razor +++ b/src/Components/test/testassets/BasicTestApp/InteropComponent.razor @@ -301,6 +301,13 @@ InvokeNewTests(); } + await FunctionReferenceAsyncTests(); + + if (shouldSupportSyncInterop) + { + FunctionReferenceTests(); + } + Invocations = invocations; DoneWithInterop = true; } @@ -601,6 +608,24 @@ } } + private async Task FunctionReferenceAsyncTests() + { + var funcRef = await JSRuntime.GetValueAsync("jsInteropTests.nonConstructorFunction"); + var testClassRef = await JSRuntime.InvokeNewAsync("jsInteropTests.TestClass", "abraka"); + await testClassRef.SetValueAsync("getTextLength", funcRef); + ReturnValues["changeFunctionViaObjectReferenceAsync"] = (await testClassRef.InvokeAsync("getTextLength")).ToString(); + } + + private void FunctionReferenceTests() + { + var inProcRuntime = ((IJSInProcessRuntime)JSRuntime); + + var funcRef = inProcRuntime.GetValue("jsInteropTests.nonConstructorFunction"); + var testClassRef = inProcRuntime.InvokeNew("jsInteropTests.TestClass", "abraka"); + testClassRef.SetValue("getTextLength", funcRef); + ReturnValues["changeFunctionViaObjectReference"] = testClassRef.Invoke("getTextLength").ToString(); + } + public class PassDotNetObjectByRefArgs { public string StringValue { get; set; } diff --git a/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts b/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts index 909207da68e0..fdd7a4ed65ec 100644 --- a/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts +++ b/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts @@ -155,7 +155,7 @@ export module DotNet { * @throws Error if the given value is not an Object. */ export function createJSObjectReference(jsObject: any): any { - if (jsObject && typeof jsObject === "object") { + if (jsObject && (typeof jsObject === "object" || jsObject instanceof Function)) { cachedJSObjectsById[nextJsObjectId] = new JSObject(jsObject); const result = {