JsInterop Array

491 views
Skip to first unread message

cesar paulo alves

unread,
Dec 19, 2017, 2:18:00 AM12/19/17
to GWT Users
Hello guys, so I'm getting crazy with this.

I need to inject a java array inside a javascript library.

The problem is that the Js library will iterate over an integer array, and if the element is not an integer it exits the function.
When I create the integer array and pass it to plain javascript array, for some reason it carries garbage inside, I already tried everything with no success.

So this is my java nodeset (https://pastebin.com/AdJqj80p)


I'm using the gwt-interop-utils -> https://github.com/GWTReact/gwt-interop-utils/blob/master/src/gwt/interop/utils/client/plainobjects/JsPlainObj.java


And when I inspect the javascript object in the browser you can see it has lots of garbage, and I cant clean it. See the nodes array I have (_clazz_0_g$,__elementTypeCategory$,_elementTypeId$"......).


And when I do the same with Js I don't have this garbage (obvious).



I already used the JsArray and everything, but no luck =/.


Do you have any Idea how to have a plain javascript array with jsInterop?


Thanks a lot.





Vassilis Virvilis

unread,
Dec 19, 2017, 3:47:52 AM12/19/17
to google-we...@googlegroups.com
I had a similar problem with DataTables requiring a String[] argument. The one generated from java had some hidden fields that DataTables choke on. I ended up creating a JsString type that casts from/to String, but at the time I didn't know or didn't exist the gwt-interop-utils.

In your case however I would suggest the following:

*** NOTE:  int and int[] are not represented in javascript *** and you may have a problem during casting in/out. I would suggest using double if/when you hit the problems. Traceback and browser's debugger is invaluable.

@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
public class NodeSet {
  public int id;
  public int x;   <-- conside use of double
  public int y;
  public int[] nodes;
  @JsOverlay
  public static NodeSet create(int id, int x, int y, int[] nodes) {
      final NodeSet ns = new NodeSet();
      ns.id = id;
      ns.x = x;
      ns.y = y;
      ns.nodes = nodes;
      return ns;
  }
}



--
You received this message because you are subscribed to the Google Groups "GWT Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsub...@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.



--
Vassilis Virvilis

Thomas Broyer

unread,
Dec 19, 2017, 5:23:10 AM12/19/17
to GWT Users
This is not "garbage", they are "expando properties".
It shouldn't be a problem in practice for any well-coded JS lib. If your JS lib fails here, it probably means it iterates over the array using a for…in loop: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in#Array_iteration_and_for...in
As a workaround, you can probably copy the array into a JsArrayInteger:
JsArrayInteger arr = JavaScriptObject.createArray().cast();
for (int node : nodes) {
  arr
.push(node);
}
or using Elemental2 Core:
JsArray<Double> arr = new JsArray<>();
for (int node : nodes) {
  arr
.push(node)
}
Message has been deleted

cesar paulo alves

unread,
Dec 19, 2017, 6:02:48 AM12/19/17
to GWT Users
Ok guys, so I apologize, after a few tests I realized something, as Thomas said about the js lib should't be reading the content, I went digger and realized that the problem was not on the expando properties but the name of the nodeSet array... The js looked for a "nodeSet" array and I was passing it as "nodeSets" array. Very sad (I'm not good with javascript). Thanks for all your help Vassills and Thomas.
I switched my code as Vassils as suggested and could find the bug(me) because of what Thomas said. Thanks a lot and sorry for taking your time.

Merry Christmas to all of you.

Cheers,
César Alves

Colin Alworth

unread,
Jan 2, 2018, 12:50:15 PM1/2/18
to GWT Users
Beware using JsArray<Double>, instead use JsArray<JsNumber>, see https://github.com/google/elemental2/issues/28.

A third option, with elemental2-core, rather than explicitly copying the array, ask the browser to do it for you with slice(). First cast the array to JsArray<JsNumber>, then slice it to get a copy of its contents, without the expandos.

JsArray<JsNumber> nodesJsArray = Js.cast(nodes);
JsNumber[] noExtraProperties = nodesJsArray.slice();

This can be handy when passing the int[] to something which refuses to handle extraneous properties, like window.postMessage. Yes, it is confusing that it appears you actually end up with a Java array, but it will not have those extra properties in this case.
Reply all
Reply to author
Forward
0 new messages