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.
Calling Client-Side Methods from the Server
You can run client-side methods from the server by accessing the Element
API.
callJsFunction
Method
The 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 a type supported by the communication mechanism. The supported types are String
, Boolean
, Integer
, Double
, JsonValue
, Element
, and Component
.
The example below uses the callJsFunction()
method to run the this.clearSelection()
function:
public void clearSelection() {
getElement().callJsFunction("clearSelection");
}
This next example uses the callJsFunction()
method to run the this.expand(otherComponentElement)
function:
public void setExpanded(Component otherComponent) {
getElement().callJsFunction("expand",
otherComponent.getElement());
}
executeJs
Method
You can also use the generic executeJs()
method to run JavaScript asynchronously from the server side. This method can be used in addition to the callJsFunction()
method when calling any JavaScript.
The 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 a type supported by the communication mechanism. The supported types are String
, Integer
, Double
, Boolean
and Element
.
Below is an example using the executeJs()
method:
public void complete() {
getElement().executeJs("MyModule.complete($0)", true);
}
It’s also possible to call the 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 UI.getCurrent().getPage().executeJs()
method instead.
Return Values
The return value from the JavaScript function called using callJsFunction()
, or the value from a return
statement in an executeJs()
expression can be accessed by adding a listener to the PendingJavaScriptResult
instance returned from either method.
This example shows how to check if the browser supports Constructable Style Sheets:
public void checkConstructableStylesheets() {
getElement().executeJs(
"return 'adoptedStyleSheets' in document")
.then(Boolean.class, supported -> {
if (supported) {
System.out.println(
"Feature is supported");
} else {
System.out.println(
"Feature isn't supported");
}
});
}
Tip
|
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 Component
subclass that can be called from the client side using the element.$server.serverMethodName(args)
notation. In client-side Polymer template code, this
refers to the corresponding element so that the calling convention is 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:
-
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 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 Promise.then()
. In an async
function, the await
keyword can also be used to wait for the result.
This example uses this.$server.getGreeting()
to call a server-side method and await
the result:
async getServerGreeting() {
let greeting = await this.$server.getGreeting("JavaScript");
console.log(greeting);
}
This next example uses this.$server.getGreeting()
to call a server-side method and wait for the result in a callback:
getServerGreeting() {
let greetingPromise = this.$server.getGreeting("JavaScript");
greetingPromise.then(greeting => console.log(greeting));
}
This last example uses the @ClientCallable
annotation on the server side:
@ClientCallable
public String getGreeting(String name) {
return "Hello " + name;
}
Important
|
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 @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 @ClientCallable
method to be available when a component is inert, you’ll need to annotate it with the @AllowInert
annotation. Consult the Server-Side Modality documentation for more information.
The example below uses the @AllowInert
annotation to allow calls to an inert component:
@ClientCallable
@AllowInert
public String getGreeting(String name) {
return "Hello " + name;
}
AB7EDF45-DB22-4560-AF27-FF1DC6944482