0

I have racked my brain on this for the better part of two days. I've read through the documentation on JSNI here as well as a few different blog posts on JSNI and passing variables like this one and nothing indicates I'm doing anything wrong. Essentially what I'm trying to do is call from my GWT Client Side class to a javascript method which I'm exporting to javascript as my class loads. That method takes params from another JS method and stores them on the instance of the Java class that I passed. That seems to work. But, once I reference those methods back in my java code, they're undefined. I believe that what is happening is that my Java Class instance is getting lost somehow after the JS finishes. Here's some code to help explain the workflow...

I have a Java Class named ProfileWidgee. That class has a method to set local variables for location, lattitude, and longitude. That method name is...

public void handleTargetPicked(String mloc, String mlat, String mlng)  {
    loc = mloc.equalsIgnoreCase("undefined") ? "" : mloc;
    lat = mlat.equalsIgnoreCase("undefined") ? "" : mlat;
    lng = mlng.equalsIgnoreCase("undefined") ? "" : mlng;
    Window.alert("setting on js side" + loc + lat + lng);
}

That method gets exported to the JS as a function using a JSNI method called exportMyFunction...

public static native void exportMyFunction(ProfileWidgee instance)/*-{
   $wnd.handleTargetPicked = $entry(
      [email protected]::handleTargetPicked(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;));

}-*/;

That all seems to go fine. It exports and I'm able to call the handleTargetPicked in my JS as follows...

handleTargetPicked(encodeURIComponent(place.formatted_address), 
    encodeURIComponent(place.geometry.location.lat()),
    encodeURIComponent(place.geometry.location.lng()));

All of this seems to work and the Window.alert() displays the correct values. That leads me to believe that it has the appropriate instance of my class and that it is setting the variables appropriately. Later on though as I'm back in my Java class, I try and reference those variables and they always come back as 'undefined.'

Window.alert("reading on the java side" + pw.getLoc() + pw.getLat() + pw.getLng());

This results in 'undefined' for all three values. So my big question is ... is it possible to set a value in your Java class from the JS side and then use that value later in your class?

1
  • Never could get an answer to this so I ended up calling DB functions to store values in database and then pull them on both sides. Commented Nov 14, 2016 at 16:18

1 Answer 1

2

I just ran into a somewhat similar situation like this and happened to see your post. I couldn't see any solutions suggested anywhere, so tried to debug it myself.

What I saw was, 'this' variable was pointing to Window rather than the object instance.

So rather than calling the method directly like e.g. handleTargetPicked(arg1, arg2), I used method.call() passing the context like e.g. handleTargetPicked.call(instance, arg1, arg2). That kind of approach solved the issue for me. Hope that helps.

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

5 Comments

This is indeed the issue. The method should be exported as a call in a function to get the proper this binding: $entry(function(loc,lat,lng) { instance.@::handleTargetPicked(*)(loc,lat,lng); })
I am also stuck at this, can you provide the correct signature for the same. is this correct? ` public static native void exportMyFunction(ProfileWidgee instance)/*-{ $wnd.handleTargetPicked = $entry( [email protected]::handleTargetPicked(Lcom/n/j/client/widgees/profile/ProfileWidgee,Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)); }-*/; `
or public static native void exportMyFunction(ProfileWidgee instance)/*-{ $wnd.handleTargetPicked = $entry( [email protected]::handleTargetPicked(this;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;));
Both incorrect. Do like this: // Suppose your method takes 3 parameters of type string - lets say arg1, arg2, arg3 var methodRef = [email protected]::handleTargetPicked(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;); methodRef.call(this, arg1, arg2, arg3);
var methodRef = [email protected]::handleleTargetPicked(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;); methodRef.call(instance, arg1, arg2, arg3);

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.