0

The JSNI method does not accept any parameters but return a Java Object type:

 public static native String nativeJSFuncGwt() /*-{
        $wnd.console.log($wnd.someJSFunc());
        return "" + $wnd.someJSFunc() + "" ;
    }-*/;


//someJSFunc returns { abc:xcv, def:asd}

I can see the value getting printed in the javascript console but java side is not able to understand the casting.

Is it because the native method does not accept any parameters ?

String tokenFromNativeJS = nativeJSFuncGwt(); // String value is null 

The documentation also is not clear enough in GWT.

Raghvendra Kumar
  • 1,328
  • 1
  • 10
  • 26

2 Answers2

5

Step one, avoid JSNI, you are better off defining a JsInterop method which provides the same API access. JSNI will still work in GWT2 but JsInterop is the way forward for GWT3, and is often much easier to read and write. This would look something like this:

@JsMethod(name = "someJSFunc", namespace = JsPackage.GLOBAL)
public static native String someJSFunc();

Step two, define a Java type which fits your expected JS return value. This will work with either JSNI or JsInterop. In JSNI you would make a JavaScriptObject subclass, and provide methods which access the fields (see http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJSNI.html and other docs for more detail, but as per step one, I'm not going to go into more depth on this here). For your example object, this would look like this in JsInterop:

@JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL)
public class SomeReturnObject {
    public String abc;
    public double def;
}

Obviously replace the field names and types with whatever is appropriate in your own project. Give this new type with the placeholder name, here's what your global someJsFunc would look like:

@JsMethod(name = "someJSFunc", namespace = JsPackage.GLOBAL)
public static native SomeReturnObject someJSFunc();

And you would use it like you expect in plain Java - no need to write JSNI any more:

SomeReturnObject object = someJSFunc();
DomGlobal.console.log(object.abc + ": " + object.def);
Colin Alworth
  • 17,801
  • 2
  • 26
  • 39
  • We have a legacy codebase which is using gwt 2.4.0 and can't be upgraded to a newer version. – Raghvendra Kumar Sep 10 '19 at 12:42
  • As long as you don't need support for any browser released in the last 8 years, that should work great. You'll need to make a JavaScriptObject subclass in this case and add the appropriate getter methods to read from those abc/def properties. For such legacy code, consider https://stackoverflow.com/a/15497221/860630 for an example, but in 2019 this is not the correct answer to a new question. – Colin Alworth Sep 10 '19 at 15:42
  • This is actually the first place I see a nice, easy, understandable, explanation on how to achieve something using Jsinterop. I always read use Jsinterop but I can't find any documentation about it. I don't think it is even mentioned on http://www.gwtproject.org/ – Knarf Sep 18 '19 at 10:17
  • 1
    @Knarf while I linked the JSNI page, there is also a JsInterop page, which discusses some of these things with short examples: http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJsInterop.html. The main power I see in a Q/A like this is that we start with a specific problem and fix it, instead of having to describe generally what the entire toolkit can do - more good questions will lead to more helpful answers! – Colin Alworth Sep 18 '19 at 12:16
0

I am posting here what finally worked for due to GWT version(2.4) constraint

From GWT Doc:

Outgoing Java type:

Any other Java Object (including arrays)

What must be passed:

Java Object of the correct type that must have originated in Java code; Java objects cannot be constructed from “thin air” in JavaScript

My code with modification would like:

public static native MyObject nativeJSFuncGwt(MyObject obj) /*-{

   var xyz = $wnd.someJsFunc();

   obj.@package.name::setter1(Ljava/lang/String;)(xyz);

   return obj;

 }-*/;

I wish documentation could have been more clear.

Raghvendra Kumar
  • 1,328
  • 1
  • 10
  • 26