AutoBean, Arrays/Lists properties and JSNI

1.2k views Asked by At

I am somehow struggling with Arrays and JSNI in the context of Autobeans.
In one of my GWT projects I retrieve a data from backend using JSON.
Once the data is retrieved on the client I want to visualize it using a custom visualization widgets (developed in javascript).

Here are the components:

JSON structure:

{'ids':[1,2,3,4],'data':[[1.0],[1.0,2.0],[1.0,2.0,3.0] ... ]}

Basically I have two datasets in my json payload. ids is a array of ints (int[]) and data is a array of arrays of floats (float[][])

There are of course different ways to parse the data on the client. I decided to use AutoBeans. So I defined an interface for my json structure.

AutoBean:

interface MyData {
   List<Integer> ids;
   List<List<Float>> data;
}

Parsing the data works fine.

My custom visualization widgets has a API function to set the data that looks like this:

function api_setData(ids,data) {
   //ids should be an Array of Ints
   //data should be an array of array of Floats.
}

The problem is that with JSNI I can't use normal Java arrays. I have to use JsArray.

public final native void setData(JsArrayInteger ids,JsArray<JsArrayInteger> data /*-{
       this.api_setData(ids,data);
    }-*/;

So I have to convert my AutoBean properties (data and ids) to JsArray instances. Is there a better/nicer way to do that?

Or maybe I should use JSONParser instead of AutoBeans Is that more efficient?

1

There are 1 answers

2
Thomas Broyer On BEST ANSWER

If you have to deal with JSNI, moreover if you're using your MyData interface only on the client-side, then don't use AutoBeans. Use JSON overlays instead:

public class MyData extends JavaScriptObject {
   protected MyData() { /* required for JSOs */ }

   public final native JsArrayInteger getIds() /*-{ return this.ids; }-*/;

   public final native JsArray<JsArrayNumber> getData() /*-{ return this.data; }-*/;
}

And then to parse your JSON:

MyData data = JsonUtils.safeEval(jsonStr);
customVisualizationWidget.setData(data.getIds(), data.getData());

Alternately, assuming you only need you parsed data for setData, then simply use JavaScriptObject.

In your widget:

public final native void setData(JavaScriptObject obj) /*-{
   this.api_setData(obj.ids, obj.data);
}-*/;

When you need to parse the JSON and give it to the widget:

customVisualizationWidget.setData(JsonUtils.safeParse(jsonStr));