3

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 ?

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

7 Comments

Leif, first of all thank you for answering. Now, to clarify things a bit, yes, my @ClientCallable is within the RouteGraphicsView class. The particular Vaadin version I'm running is 14.7.0 (if that's of any interest). Secondly, there is a difference between what the tutorial is saying I should do for getting from Java to JavaScript. The tutorial says I should be doing getElement().executeJavaScript for calling the function in the .js file. When I try to do this nothing happens on the javascript side of things. It's only when I do UI.getCurrent().getElement().executeJs things start to go
Now, I tried your suggestion and changed the UI.getCurrent().getPage().executeJs("greet($0, $1)", "test name", UI.getCurrent().getElement()); to UI.getCurrent().getPage().executeJs("greet($0, $1)", "test name", RouteGraphicsView.this); but without any luck. If you have any other suggestions I would be glad to hear them.
When I output the arguments that my greet function receives, the second one - e.g. the class instance of RouteGraphicsView is null while the first one (a simple String) is logged and received as expected.
There is a similar post to what I'm experiencing here stackoverflow.com/questions/69192087/…
I assembled the different snippets into something that works as a whole by adding @Route to the class and add(b); to the constructor. With those small adjustments, the example works for me when I pass RouteGraphicsView.this as the second argument to executeJs. It shouldn't have any impact, but I used a different Vaadin version. You could try with the latest 14.x release, i.e. 14.8.20.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.