diff --git a/aspnetcore/blazor/javascript-interoperability/call-javascript-from-dotnet.md b/aspnetcore/blazor/javascript-interoperability/call-javascript-from-dotnet.md index e7146908f3a2..e20af5fc6404 100644 --- a/aspnetcore/blazor/javascript-interoperability/call-javascript-from-dotnet.md +++ b/aspnetcore/blazor/javascript-interoperability/call-javascript-from-dotnet.md @@ -453,6 +453,107 @@ IJSRuntime JS { get; set; } [!INCLUDE[](~/blazor/includes/js-interop/synchronous-js-interop-call-js.md)] +:::moniker range=">= aspnetcore-10.0" + + + +## Create an instance of a JS object using a constructor function + +Create an instance of a JS object using a constructor function and get the / .NET handle for referencing the instance with the following API: + +* `InvokeNewAsync` (asynchronous) +* `InvokeNew` (synchronous) + +Examples in this section demonstrate the API calls with the following `TestClass` with a constructor function (`constructor(text)`): + +```javascript +window.TestClass = class { + constructor(text) { + this.text = text; + } + + getTextLength() { + return this.text.length; + } +} +``` + +### Asynchronous `InvokeNewAsync` + +Use `InvokeNewAsync(string identifier, object?[]? args)` on and to invoke the specified JS constructor function asynchronously. The function is invoked with the `new` operator. In the following example, `TestClass` contains a constructor function, and `classRef` is an . + +```csharp +var classRef = await JSRuntime.InvokeNewAsync("TestClass", "Blazor!"); +var text = await classRef.GetValueAsync("text"); +var textLength = await classRef.InvokeAsync("getTextLength"); +``` + +An overload is available that takes a argument or timeout argument. + +### Synchronous `InvokeNew` + +Use `InvokeNew(string identifier, object?[]? args)` on and to invoke the specified JS constructor function synchronously. The function is invoked with the `new` operator. In the following example, `TestClass` contains a constructor function, and `classRef` is an : + +```csharp +var inProcRuntime = ((IJSInProcessRuntime)JSRuntime); +var classRef = inProcRuntime.InvokeNew("TestClass", "Blazor!"); +var text = await classRef.GetValueAsync("text"); +var textLength = await classRef.InvokeAsync("getTextLength"); +``` + +An overload is available that takes a argument or timeout argument. + +## Read or modify the value of a JS object property + +Read or modify the value of a JS object property, both data and accessor properties, with the following API: + +* `GetValueAsync`/`SetValueAsync` (asynchronous) +* `GetValue`/`SetValue` (synchronous) + +Examples in this section demonstrate the API calls with the following JS object (`testObject`): + +```javascript +window.testObject = { + num: 10 +} +``` + +### Asynchronous `GetValueAsync` and `SetValueAsync` + +Use `GetValueAsync(string identifier)` to read the value of the specified JS property asynchronously. A is thrown if the property doesn't exist or is a `set`-only property. In the following example, the value of `testObject.num` (10) is stored in `valueFromDataPropertyAsync`: + +```csharp +var valueFromDataPropertyAsync = + await JSRuntime.GetValueAsync("testObject.num"); +``` + +Use `SetValueAsync(string identifier, TValue value)` to update the value of the specified JS property asynchronously. If the property isn't defined on the target object, the property is created. A is thrown if the property exists but isn't writable or when a new property can't be added to the object. In the following example, `testObject.num` is set to 20, and `num2` is created with a value of 30 on `testObject`: + +```csharp +await JSRuntime.SetValueAsync("testObject.num", 20); +await JSRuntime.SetValueAsync("testObject.num2", 30); +``` + +### Synchronous `GetValue` and `SetValue` + +Use `GetValue(string identifier)` to read the value of the specified JS property synchronously. A is thrown if the property doesn't exist or is a `set`-only property. In the following example, the value of `testObject.num` (10) is stored in `valueFromDataProperty`: + +```csharp +var inProcRuntime = ((IJSInProcessRuntime)JSRuntime); +var valueFromDataProperty = inProcRuntime.GetValue("testObject.num"); +``` + +Use `SetValue(string identifier, TValue value)` to update the value of the specified JS property synchronously. The property can't be a `get`-only property. If the property isn't defined on the target object, the property is created. A is thrown if the property exists but isn't writable or when a new property can't be added to the object. In the following example, `testObject.num` is set to 20, and `num2` is created with a value of 30 on `testObject`: + +```csharp +var inProcRuntime = ((IJSInProcessRuntime)JSRuntime); +inProcRuntime.SetValue("testObject.num", 20); +inProcRuntime.SetValue("testObject.num2", 30); +``` + +:::moniker-end + ## JavaScript location Load JavaScript (JS) code using any of approaches described by the [article on JavaScript location](xref:blazor/js-interop/javascript-location): @@ -519,12 +620,35 @@ For browser compatibility, see [Can I use: JavaScript modules: dynamic import](h In server-side scenarios, JS interop calls can't be issued after Blazor's SignalR circuit is disconnected. Without a circuit during component disposal or at any other time that a circuit doesn't exist, the following method calls fail and log a message that the circuit is disconnected as a : +:::moniker-end + +:::moniker range=">= aspnetcore-10.0" + + + * JS interop method calls * * - * ) + * + * `InvokeNewAsync` + * `GetValueAsync` + * `SetValueAsync` * `Dispose`/`DisposeAsync` calls on any . +:::moniker-end + +:::moniker range=">= aspnetcore-5.0 < aspnetcore-10.0" + +* JS interop method calls + * + * + * +* `Dispose`/`DisposeAsync` calls on any . + +:::moniker-end + +:::moniker range=">= aspnetcore-5.0" + In order to avoid logging or to log custom information in server-side Blazor, catch the exception in a [`try-catch`](/dotnet/csharp/language-reference/keywords/try-catch) statement. For the following component disposal example: @@ -627,7 +751,7 @@ In the preceding example: Dynamically importing a module requires a network request, so it can only be achieved asynchronously by calling . -`IJSInProcessObjectReference` represents a reference to a JS object whose functions can be invoked synchronously in client-side components. For more information, see the [Synchronous JS interop in client-side components](#synchronous-js-interop-in-client-side-components) section. + represents a reference to a JS object whose functions can be invoked synchronously in client-side components. For more information, see the [Synchronous JS interop in client-side components](#synchronous-js-interop-in-client-side-components) section. > [!NOTE] > When the external JS file is supplied by a [Razor class library](xref:blazor/components/class-libraries), specify the module's JS file using its stable static web asset path: `./_content/{PACKAGE ID}/{SCRIPT PATH AND FILE NAME (.js)}`: diff --git a/aspnetcore/blazor/javascript-interoperability/index.md b/aspnetcore/blazor/javascript-interoperability/index.md index 23a56e202d95..3b0721618cc6 100644 --- a/aspnetcore/blazor/javascript-interoperability/index.md +++ b/aspnetcore/blazor/javascript-interoperability/index.md @@ -328,12 +328,31 @@ Don't assume that observing `document.body`, instead of `target.parentNode`, is JavaScript (JS) interop calls can't be issued after Blazor's SignalR circuit is disconnected. Without a circuit during component disposal or at any other time that a circuit doesn't exist, the following method calls fail and log a message that the circuit is disconnected as a : +:::moniker range=">= aspnetcore-10.0" + + + * JS interop method calls * * * + * `InvokeNewAsync` + * `GetValueAsync` + * `SetValueAsync` * `Dispose`/`DisposeAsync` calls on any . +:::moniker-end + +:::moniker range="< aspnetcore-10.0" + +* JS interop method calls + * + * + * +* `Dispose`/`DisposeAsync` calls on any . + +:::moniker-end + In order to avoid logging or to log custom information, catch the exception in a [`try-catch`](/dotnet/csharp/language-reference/keywords/try-catch) statement. For the following component disposal example: diff --git a/aspnetcore/release-notes/aspnetcore-10/includes/blazor.md b/aspnetcore/release-notes/aspnetcore-10/includes/blazor.md index 1d1cdce507c1..ccf25f2e19d5 100644 --- a/aspnetcore/release-notes/aspnetcore-10/includes/blazor.md +++ b/aspnetcore/release-notes/aspnetcore-10/includes/blazor.md @@ -280,3 +280,70 @@ else ``` For more information, see . Additional API implementation notes, which are subject to change at any time, are available in [[Blazor] Support for declaratively persisting component and services state (`dotnet/aspnetcore` #60634)](https://github.com/dotnet/aspnetcore/pull/60634). + +