Skip to content

Commit

Permalink
docs: add note about AllowInert on RPC calls (#3111)
Browse files Browse the repository at this point in the history
* docs: add note about AllowInert on RPC calls

Adds a note about the usage of AllowInert annotation to allow RPC calls
to components behind a modal dialog or component.

Fixes vaadin/flow#17496

* First pass at editing.

* Second pass -- edited rest of document touched.

---------

Co-authored-by: russelljtdyer <[email protected]>
  • Loading branch information
mcollovati and russelljtdyer authored Jan 29, 2024
1 parent b77a760 commit 4c8800c
Showing 1 changed file with 48 additions and 38 deletions.
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

0 comments on commit 4c8800c

Please sign in to comment.