I have the following entity in GWT
@JsType(namespace = "my.entities")
public class MyEntity {
private Set<String> texts;
public Set<String> getTexts(){
if(this.texts==null)
this.texts=new LinkedHashSet<String>();
return this.texts;
}
public void setTexts(Set<String> texts){
this.texts=texts;
}
}
When I call myEntityVar.getTexts() in Javascript the returned object is a HashSet. It seems like jsinterop converts the java implementation of HashSet to JavaScript. But how can I create a new HashSet in JavaScript in order to use myEntityVar.setTexts(texts)? I tried an array for the "texts" param, but that doesn't work. So I somehow need to use HashSet in JavaScript.
However, I can't figure out, where to find it.
Any idea?
The short answer is that you can't - but then again, you also can't create a plain HashSet in JS either!
The reason that this works at all is that you've enabled
-generateJsInteropExports, and while there is a JsInterop annotation on yourMyEntitytype, there is also one onjava.util.Set(and a few other base JRE types). This allows for your code to return emulated java Sets without issue - any method which is compatible with running in JS is supported.There are a few downsides:
toArray()andtoArray(T[])look like the same method in JS. GWT solves this by not supporting the second method at all. (java.util.Listhas the same issue withremove(T)andremove(int), but it resolves it by renamingremove(int)toremoveAtIndex(int)when compiled.)If you never return these types, you'll probably want to disable this feature entirely - the
-excludeJsInteropExportsand-includeJsInteropExportsflags to the compiler let you control what is exported.To answer your question more directly, you have a few options that I can see:
setTextsmethod to be passed something else from JS, such as aJsArrayLikeso that you could let users pass in a plain JS array of strings, or even a JS Set. You could go further and acceptObject, and then type-check it to see what was passed in. You could even leave theSetoverride so it could be called from your own Java if necessary, but mark it as@JsIgnoreso that GWT doesn't break when you attempt to export overloaded methods.Create a factory method somewhere to create the Set implementation you would like your JS users to use. Since
addandremoveare supported, the calling JS code can build up the set before passing it in. Something like this:Now they can call
my.Util.createSet(), append items, and then pass it to your setTexts method.