Skip to content

docs: add note about AllowInert on RPC calls #3111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 48 additions & 38 deletions articles/create-ui/element-api/client-server-rpc.asciidoc
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
---
title: Remote Procedure Calls
description: How to run procedures or subroutines elsewhere, on another machine.
description: Running procedures or subroutines elsewhere -- on another machine.
order: 3
---


= Remote Procedure Calls

Remote procedure calls (RPCs) are a way to run procedures or subroutines in a different address space, typically on another machine. Vaadin Flow handles server-client communication by allowing RPC calls from the server to the client, and _vice versa_.
Remote procedure calls (RPCs) are a way to run procedures or subroutines in a different address space, typically on another machine. Vaadin Flow handles server-client communication by allowing RPC calls from the server to the client -- and vice versa.


== Calling Client-Side Methods from the Server

You can run client-side methods from the server by accessing the [classname]`Element` API.


=== `callJsFunction` Method

The [methodname]`callJsFunction()` method allows you to run a client-side component function from the server side.
The method accepts two parameters: the name of the function to call, and the arguments to pass to the function.
The [methodname]`callJsFunction()` method allows you to run a client-side component function from the server side. The method accepts two parameters: the name of the function to call; and the arguments to pass to the function.

The arguments passed to the function must be of a type supported by the communication mechanism.
The supported types are `String`, `Boolean`, `Integer`, `Double`, `JsonValue`, `Element`, and `Component`.
The arguments passed to the function must be a type supported by the communication mechanism. The supported types are `String`, `Boolean`, `Integer`, `Double`, `JsonValue`, `Element`, and `Component`.

*Example*: Using the [methodname]`callJsFunction()` method to run the [methodname]`this.clearSelection()` function.
The example below uses the [methodname]`callJsFunction()` method to run the [methodname]`this.clearSelection()` function:

[source,java]
----
Expand All @@ -30,7 +30,7 @@ public void clearSelection() {
}
----

*Example*: Using the [methodname]`callJsFunction()` method to run the [methodname]`this.expand(otherComponentElement)` function.
This next example uses the [methodname]`callJsFunction()` method to run the [methodname]`this.expand(otherComponentElement)` function:

[source,java]
----
Expand All @@ -40,18 +40,16 @@ public void setExpanded(Component otherComponent) {
}
----


=== `executeJs` Method

You can also use the generic [methodname]`executeJs()` method to run JavaScript asynchronously from the server side.
You can use this method in addition to the [methodname]`callJsFunction()` method when calling any JavaScript.
You can also use the generic [methodname]`executeJs()` method to run JavaScript asynchronously from the server side. This method can be used in addition to the [methodname]`callJsFunction()` method when calling any JavaScript.

The [methodname]`executeJs()` method accepts two parameters: the JavaScript expression to invoke, and the parameters to pass to the expression.
The given parameters are available as variables named `$0`, `$1`, and so on.
The [methodname]`executeJs()` method accepts two parameters: the JavaScript expression to invoke; and the parameters to pass to the expression. The given parameters are available as variables named `$0`, `$1`, and so on.

The arguments passed to the expression must be of a type supported by the communication mechanism.
The supported types are `String`, `Integer`, `Double`, `Boolean` and `Element`.
The arguments passed to the expression must be a type supported by the communication mechanism. The supported types are `String`, `Integer`, `Double`, `Boolean` and `Element`.

*Example*: Using the [methodname]`executeJs()` method.
Below is an example using the [methodname]`executeJs()` method:

[source,java]
----
Expand All @@ -60,14 +58,14 @@ public void complete() {
}
----

It's also possible to call the [methodname]`executeJs()` method to access methods and fields of a Web Component using `this.myFieldName`.
If the element doesn't need to be initialized first, you can use the [methodname]`UI.getCurrent().getPage().executeJs()` method instead.
It's also possible to call the [methodname]`executeJs()` method to access methods and fields of a Web Component using `this.myFieldName`. If the element doesn't need to be initialized, you can use the [methodname]`UI.getCurrent().getPage().executeJs()` method instead.


=== Return Values

The return value from the JavaScript function called using [methodname]`callJsFunction()` or the value from a `return` statement in an `executeJs()` expression can be accessed by adding a listener to the [classname]`PendingJavaScriptResult` instance returned from either method.
The return value from the JavaScript function called using [methodname]`callJsFunction()`, or the value from a `return` statement in an `executeJs()` expression can be accessed by adding a listener to the [classname]`PendingJavaScriptResult` instance returned from either method.

*Example*: Check if the browser supports Constructable Style Sheets.
This example shows how to check if the browser supports Constructable Style Sheets:

[source,java]
----
Expand All @@ -87,31 +85,29 @@ public void checkConstructableStylesheets() {
----

[TIP]
If the return value is a JavaScript `Promise`, then a return value is sent to the server only when the `Promise` is resolved.
If the return value is a JavaScript `Promise`, a return value is sent to the server only when the `Promise` is resolved.


== Calling Server-Side Methods from the Client

Below are a few server-side methods that may be called from the client.


=== `@ClientCallable` Annotation

The `@ClientCallable` annotation allows you to invoke a server-side method from the client side.
It marks a method in a [classname]`Component` subclass that can be called from the client side using the [methodname]`element.$server.serverMethodName(args)` notation.
In client-side Polymer template code, `this` refers to the corresponding element, so that the calling convention is [methodname]`this.$server.serverMethodName(args)`.
The `@ClientCallable` annotation allows you to invoke a server-side method from the client side. It marks a method in a [classname]`Component` subclass that can be called from the client side using the [methodname]`element.$server.serverMethodName(args)` notation. In client-side Polymer template code, `this` refers to the corresponding element so that the calling convention is [methodname]`this.$server.serverMethodName(args)`.

You can use it anywhere in your client-side Polymer class implementation, and you can pass your own arguments in the method.
The types should match the method declaration on the server side.
The supported argument types are:
You can use it anywhere in your client-side Polymer class implementation, and you can pass your own arguments in the method. The types should match the method declaration on the server side. The supported argument types are:

- `boolean` , `int`, `double`, their boxed types (`Boolean` , `Integer`, `Double`)
- `String`
- `JsonValue`
- enumeration type which is addressed via a string value from the client-side JavaScript
- `TemplateModel` property types (see <<{articles}/create-ui/templates/polymer/model-bean#,Using Beans with a PolymerTemplate Model>>
- `boolean` , `int`, `double`, their boxed types (i.e., `Boolean` , `Integer`, `Double`);
- `String`;
- `JsonValue`;
- enumeration type which is addressed via a string value from the client-side JavaScript; and
- `TemplateModel` property types (see <<{articles}/create-ui/templates/polymer/model-bean#,Using Beans with a PolymerTemplate Model>>).

The client-side method returns a Promise which is resolved asynchronously with the return value from the server, or `null` if the server-side return type is `void`.
You can wait for the result using [methodname]`Promise.then()`.
In an `async` function, the `await` keyword can also be used to wait for the result.
The client-side method returns a Promise, which is resolved asynchronously with the return value from the server, or `null` if the server-side return type is `void`. You can wait for the result using [methodname]`Promise.then()`. In an `async` function, the `await` keyword can also be used to wait for the result.

*Example*: Using [methodname]`this.$server.getGreeting()` to call a server-side method and `await` the result.
This example uses [methodname]`this.$server.getGreeting()` to call a server-side method and `await` the result:

[source,javascript]
----
Expand All @@ -121,7 +117,7 @@ async getServerGreeting() {
}
----

*Example*: Using [methodname]`this.$server.getGreeting()` to call a server-side method and wait for the result in a callback.
This next example uses [methodname]`this.$server.getGreeting()` to call a server-side method and wait for the result in a callback:

[source,javascript]
----
Expand All @@ -131,7 +127,8 @@ getServerGreeting() {
}
----

*Example*: Using the `@ClientCallable` annotation on the server side.
This last example uses the `@ClientCallable` annotation on the server side:

[source,java]
----
@ClientCallable
Expand All @@ -141,7 +138,20 @@ public String getGreeting(String name) {
----

[IMPORTANT]
Property changes, DOM events, client-delegate methods (methods annotated with `@ClientCallable`) and event-handler methods (`PolymerTemplate` methods annotated with `@EventHandler`) are blocked for disabled components.
Property changes, DOM events, client-delegate methods (i.e., methods annotated with `@ClientCallable`), and event-handler methods (i.e., `PolymerTemplate` methods annotated with `@EventHandler`) are blocked for disabled components.

It's worth noting that if a component with the [annotationname]`@ClientCallable` method is underneath a modal dialog or component, it's considered _inert_. That means it's not available for interaction, including RPC calls. If you want the [annotationname]`@ClientCallable` method to be available when a component is inert, you'll need to annotate it with the [annotationname]`@AllowInert` annotation. Consult the <<{articles}/advanced/server-side-modality#,Server-Side Modality documentation>> for more information.

The example below uses the `@AllowInert` annotation to allow calls to an inert component:

[source,java]
----
@ClientCallable
@AllowInert
public String getGreeting(String name) {
return "Hello " + name;
}
----


[discussion-id]`AB7EDF45-DB22-4560-AF27-FF1DC6944482`
Expand Down