@ClientCallable annotation

My problem references to this page: https://vaadin.com/docs/latest/create-ui/element-api/client-server-rpc

This is my page built with Vaadin:

@Route("")
@JsModule("./src/testen_funktion.js")
public class HelloWorldView extends VerticalLayout {

  @ClientCallable
  public String getGreeting(String name) {
    return "Hello " + name;
  }
};

It is an empty page. I just want to call a Js function to write a string in the browser console.

Here is the Js code taken from Vaadin page:

async function getServerGreeting() {
    let greeting = await this.$server.getGreeting("JavaScript");
    console.log(greeting);
  }

Empty page is shown but there is no string in the browser console.
What is wrong with my code?

Who is calling the getServerGreeting() function on the client code?

What do you mean?

I just copied the codes and pasted them.

The function you added in the javascript file is supposed to be called by someone.
How does your js file looks like? Only the function definition?
If so, you also need to invoke it

Can you show me that please?

Yes, it is only the function definition.

For example you can have a button in the Java view that triggers the client side function
something like

new Button("Exec client function", ev -> getElement().executeJs("this.getServerGreeting();"))

I see, that function must somehow be triggered.

exactly

Is the semicolon correct inside executeJs function?

It has to be a valid JS expression, So I suppose it is ok, but in this case you can also remove it

@ClientCallable
  public String getGreeting(String name) {
    add(button);
    button.setText("Testen");
    button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
    button.addClickListener(event -> { 
      getElement().executeJs("this.getServerGreeting();");
    });
    return "Hello " + name;
  }

Is that ok?

Nope

You should not add the button in the client callable

Add it in your view constructor

otherwise it will never be added because, nobody is calling the client callable method

public HelloWorldView() {
    add(button);
    button.setText("Testen");
    button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
  }

  @ClientCallable
  public String getGreeting(String name) {
    button.addClickListener(event -> {
      getElement().executeJs("this.getServerGreeting();");
    });
    return "Hello " + name;
  }

The button must be in the view to trigger the client side function, so that in turn can call the client callable

public HelloWorldView() {
    add(button);
    button.setText("Testen");
    button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
    button.addClickListener(event -> {
      getElement().executeJs("this.getServerGreeting();");
    });
  }

  @ClientCallable
  public String getGreeting(String name) {
    return "Hello " + name;
  }