Following this tutorial https://vaadin.com/blog/calling-java-from-javascript I'm trying to call a Java function from javascript but that doesn't seem to work as expected.
I'm having a View that contains a button which, on its onClick handler, triggers a call to a Javascript function, which works as expected.
The problem I'm having is that the getElement() that I`m passing to the javascript function is undefined when it reaches the javascript side of things.
My code looks as follows:
@JavaScript("./js/script.js")
public class RouteGraphicsView extends Div {
....
Button b = new Button("Test Button");
b.addClickListener(new ComponentEventListener<ClickEvent<Button>>() {
private static final long serialVersionUID = 1L;
@Override
public void onComponentEvent(final ClickEvent<Button> event) {
UI.getCurrent().getPage().executeJs("greet($0, $1)", "test name", UI.getCurrent().getElement());
}
});
....
}
The above call reaches the script.js file which looks like this
window.greet = function greet(name, element) {
console.log("Hello, I am greeting you, " + name);
try {
console.log("Element ", element);
console.log("Logging 1", element.$server);
} catch (e) {
console.log(e);
}
}
The output shown by the greet function above is
Hello, I am greeting you, test name
vaadin-bundle-62ac8b…b56c6.cache.js:4813 Element
vaadin-bundle-62ac8b…b56c6.cache.js:4813 Logging 1 undefined
Since the element.$server is undefined I can not get the javascript function to call my greet function in the View, which is annotated with @ClientCallable
@ClientCallable
public void greet(final String name) {
System.out.println("Called from JavaScript: " + name + " \n\n\n");
}
I've tried various other ways of calling the script.js, like using button's element to invoke the executeJs function or passing the button's element (b.getElement()) as an argument to the function but to no avail.
What am I doing wrong ?
You're doing element.$server
on the element that you passed as UI.getCurrent().getElement()
. This corresponds to the UI instance and not an instance of the RouteGraphicsView
class that (I assume) has the @ClientCallable
method. Using the button would also not work for the same reason.
You should pass an instance of the view, which in your case needs to be written as RouteGraphicsView.this
because of the way the regular this
refers to the click listener.