I have a java array of String, and now I want to pass it into a JSNI function. I try to use JsArrayString
in GWT, however I find that it can not be initialized directly, because it doesn't have a visible constructor. So how can I pass my String array into the JSNI function and use it in my javascript code? The code is looks like follows:
public void callJSNI() {
String[] stringArray = xxx;
//How should I convert the array into a JSNI-readable format here?
}
private native void JSNIMethod(JsArrayString array) /*-{
//some code to use the array in javascript
}-*/
The API does not provide an easy way to do it, you'd have to create a utility method that will:
Something like this:
public static JsArrayString toJsArray(String[] input) {
JsArrayString jsArrayString = createEmptyJsArrayString();
for (String s : input) {
jsArrayString.push(s);
}
return jsArrayString;
}
private static native JsArrayString createEmptyJsArrayString() /*-{
return [];
}-*/;
As the OP suggested, we can, of course, skip the native initialization and use JsArrayString.createArray()
.
Now we can get rid of the native initialization, so our code reduces to this:
public static JsArrayString toJsArray(String[] input) {
JsArrayString jsArrayString = JsArrayString.createArray().cast();
for (String s : input) {
jsArrayString.push(s);
}
return jsArrayString;
}
The answer of Eliran Malka is a good starting point. But be aware that there is an extendend soloution that is much more efficient in some cases. That's why I create another answer.
The simple solution is this:
public static JsArrayString toJsArray(String[] input) {
JsArrayString jsArrayString = JsArrayString.createArray().cast();
for (String s : input) {
jsArrayString.push(s);
}
return jsArrayString;
}
The extended/more efficient solution needs some background knowledge...
The GWT compiler uses JS arrays when the Java code used Java arrays. So in this case you already have a JS array. But this can lead to side-effects that result in different behavior in Dev and Prod mode:
As we have real Java arrays in Dev mode, a conversion to a JS array by copying the values is always necessary. Manipulations in one of the arrays won't be visible to the other array.
In Prod mode if we use the Java array directly as JS array we would only have one array at all. So manipulations in either Java or JS code would affect the other world.
But if the following things apply to your use-case, you can use the array without creating another one:
In this case you will not have side effects (different behavior in Dev and Prod mode) and the array can directly be used in the native code.
This kind of implementation is contained in GWT's JsArrayUtils. But unfortunately there is currently no implementation for String arrays. But the implementation will look like this:
public static JsArrayString readOnlyJsArray(String[] array) {
if (GWT.isScript()) {
return arrayAsJsArrayForProdMode(array).cast();
}
JsArrayString dest = JsArrayString.createArray().cast();
for (int i = 0; i < array.length; ++i) {
dest.push(array[i]);
}
return dest;
}
private static native JavaScriptObject arrayAsJsArrayForProdMode(Object array) /*-{
return array;
}-*/;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With