Looks better indeed. Are there also some other reasons not to use JSNI? Eg. 
performance, or it is going to be removed in future?

How would I call  Array.prototype.push.apply(arrayList, value); via 
JsInterop? Or if I wanted to add a function to an existing object?

Thank you,
Marcin

On Wednesday, 10 May 2017 20:02:46 UTC+2, Daniel Kurka wrote:
>
> First of all do not use JSNI going forward.
>
> Use elemental2 (or define your own JSON.parse):
>
> Without elemental2:
> @JsType(isNative=true, namespace = JsPackage.GLOBAL);
> public class JSON {
>   public static Object parse(String s, Reviver r);
> }
>
> @JsFunction
> public interface Reviver {
>   public Object run(String key, Object value);
> }
>
> // usage:
> MyObject o = (MyObject) JSON.parse(s, (key, value) -> {
>   // whatever change you need to do
>   return value;
> });
>
> -Daniel
>
> On Wed, May 10, 2017 at 9:53 AM <[email protected] <javascript:>> 
> wrote:
>
>>
>> I am still new to GWT (so this code is probably naive), but I implemented 
>> this JSON parse wrapper which performs "transparent" conversion of JS 
>> arrays to java.util.List and using replacer/reviver functions:
>>
>> https://github.com/bpilot/jclosure/blob/master/src/main/java/ailabs/jclosure/client/encoding/json/JsonParser.java
>>
>> Could this be made more general?
>>
>>
>> On Wednesday, May 10, 2017 at 11:40:53 AM UTC-4, Marcin Okraszewski wrote:
>>>
>>> I've done something that I think is so far the closest to what I want to 
>>> achieve - the same object behaving as List in Java and as array in JS. 
>>> Actually it can be seen in Java as either list or array - both work :-)
>>>
>>> First I declare JsArray:
>>>
>>> @JsType(isNative=true, name="Array", namespace=JsPackage.GLOBAL)
>>> public class JsArray<E> {
>>>   // JS method declarations here, but can be also empty
>>> }
>>>
>>>
>>> Then extend create a List that extends the JsArray
>>>
>>> @JsType
>>> public class JsArrayList<E> extends JsArray<E> implements List<E> {
>>>   // List implementation here
>>> }
>>>
>>>
>>> Now, parse JSON and replace arrays with instances of JsArrayList.
>>>
>>> private static native <T> T parse(String json) /*-{
>>> return JSON.parse(json, function(key, value) {
>>> if (Array.isArray(value)) {
>>> var arrayList = new @interop.client.JsArrayList::new();
>>> Array.prototype.push.apply(arrayList, value);
>>> value = arrayList;
>>> }
>>> return value;
>>> });
>>> }-*/;
>>>
>>> Now, if the JSON includes any array, you will be able to use in Java as 
>>> List.
>>>
>>> Problems so far:
>>>
>>>    1. All elements of the array need to be copied. I was tempted to 
>>>    just change __proto__ with the one from JsArrayList, but that is said to 
>>>    affect performance. I could also add methods from JsArrayList to the 
>>>    instance, not sure if that is better from performance standpoint. 
>>>    2. The extended array is not recognized as an array in JS (although 
>>>    it behaves as array). Array.isArray() returns false, same for instanceof 
>>>    Array. I guess, adding functions to array instance would solve it. 
>>>    3. While parsing metadata are missing, what actual type should that 
>>>    be. Switching arrays to list is a decision without context. But when we 
>>>    want to treat an object as map, then it would need to be known somehow. 
>>> It 
>>>    can be naming convention of fields, but it is not perfect; could not 
>>>    supported nested collections. Some meta provided from the interface that 
>>> is 
>>>    being cased, would be great. 
>>>
>>> Do you have any thoughts on that maybe?
>>>
>>> Thank you,
>>> Marcin
>>>
>>>
>>> On Wednesday, 10 May 2017 01:19:58 UTC+2, Ray Cromwell wrote:
>>>>
>>>> I think it would be better to use a JsArrayListAdapter in order to 
>>>> prevent making copies all over the place, and also making mutations 
>>>> write-through on both sides e.g.
>>>>
>>>> public class JsArrayListAdapter<T> extends AbstractList<T> {
>>>>    public JsArrayListAdapter(ArrayLike<T> blah) {
>>>>       this.array = blah;
>>>>   }
>>>>
>>>>   // implement List methods to delegate to Array methods
>>>> }
>>>>
>>>> To keep referential integrity, you need to use an expando or ES6 Symbol 
>>>> property to hide a backreference.
>>>>
>>>> That is, JsArrayListAdapter.wrap(nativeJsArray) == 
>>>> JsArrayListAdapter.wrap(nativeJsArray2) IFF nativeJsArray == 
>>>> nativeJsArray2.
>>>>
>>>> This technique is less error prone IMHO if you are going to have 
>>>> mutable objects. If you're using immutables, then making copies is 
>>>> superior.
>>>>
>>>>
>>>>  
>>>>
>>>>
>>>> On Tue, May 9, 2017 at 3:24 PM 'Goktug Gokdogan' via GWT Contributors <
>>>> [email protected]> wrote:
>>>>
>>>>> Yes, theoretically you should be able to use the second parameter on 
>>>>> Json.parse Json.stringify for conversion back and forth between java 
>>>>> collections and js primitives. In this model, your javascript code needs 
>>>>> to 
>>>>> use Java collection APIs.
>>>>>
>>>>> > java.util.Arrays.asList() should be enough
>>>>>
>>>>> keep in mind that Arrays.asList won't let you go out of bounds.
>>>>>
>>>>>
>>>>>
>>>>> > I believe it was in plans with @JsConvert
>>>>>
>>>>>
>>>>> We are not working on @JsConvert right now. JsConvert is just 
>>>>> convenience and you can mimic it:
>>>>>
>>>>>
>>>>>   @JsType(isNative=true)
>>>>>   interface MyType {
>>>>>      @JsConvert(ListConverter.class)
>>>>>      List getMyArray()
>>>>>      void setMyArray(@JsConvert(ListConverter.class) List array)
>>>>>   }
>>>>>
>>>>> is roughly equivalent to:
>>>>>
>>>>>   @JsType(isNative=true)
>>>>>   interface MyType {
>>>>>      @JsProperty(name="myArray")
>>>>>      Object[] getMyArrayInternal();
>>>>>
>>>>>      @JsOverlay
>>>>>      default List getMyArray() { return Arrays.asList(getMyArray()); }
>>>>>
>>>>>      @JsProperty(name="myArray")
>>>>>      void setMyArrayInternal(Object[] array);
>>>>>
>>>>>      @JsOverlay
>>>>>      default void setMyArray(List list) {
>>>>>        setMyArrayInternal(array.toArray());
>>>>>      }
>>>>>   }
>>>>>
>>>>>
>>>>> On Tue, May 9, 2017 at 9:32 AM, Thomas Broyer <[email protected]> 
>>>>> wrote:
>>>>>
>>>>>>
>>>>>>
>>>>>> On Tuesday, May 9, 2017 at 4:34:48 PM UTC+2, Marcin Okraszewski wrote:
>>>>>>>
>>>>>>> There is indeed something in it. Actually you could have some type 
>>>>>>> of naming convention, like in TJSON (
>>>>>>> https://tonyarcieri.com/introducing-tjson-a-stricter-typed-form-of-json)
>>>>>>>  
>>>>>>> or TypedJson (https://www.npmjs.com/package/typed-json) to figure 
>>>>>>> out proper types. But then I would need to create eg. ArrayList with 
>>>>>>> the 
>>>>>>> Manuel's trick (the asList() from Polymer). I'll test it. 
>>>>>>>
>>>>>>
>>>>>> java.util.Arrays.asList() should be enough actually: 
>>>>>> https://github.com/gwtproject/gwt/blob/2.8.1/user/super/com/google/gwt/emul/java/util/Arrays.java#L136
>>>>>>  
>>>>>> (note that the ArrayList there is not java.util.ArrayList, it's an 
>>>>>> internal 
>>>>>> java.util.Arrays.ArrayList class that directly wraps the array with no 
>>>>>> copy).
>>>>>>
>>>>>> -- 
>>>>>> You received this message because you are subscribed to the Google 
>>>>>> Groups "GWT Contributors" group.
>>>>>> To unsubscribe from this group and stop receiving emails from it, 
>>>>>> send an email to 
>>>>>> [email protected].
>>>>>> To view this discussion on the web visit 
>>>>>> https://groups.google.com/d/msgid/google-web-toolkit-contributors/95e1bd43-b4a6-4b2d-bd89-6cc6fb206631%40googlegroups.com
>>>>>>  
>>>>>> <https://groups.google.com/d/msgid/google-web-toolkit-contributors/95e1bd43-b4a6-4b2d-bd89-6cc6fb206631%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>> .
>>>>>>
>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>>
>>>>> -- 
>>>>> You received this message because you are subscribed to the Google 
>>>>> Groups "GWT Contributors" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>>> an email to 
>>>>> [email protected].
>>>>> To view this discussion on the web visit 
>>>>> https://groups.google.com/d/msgid/google-web-toolkit-contributors/CAN%3DyUA0Wr0pWKUcqyN2YMkuoZZK7b3e-ipm7jqv2DdDeqk8sMA%40mail.gmail.com
>>>>>  
>>>>> <https://groups.google.com/d/msgid/google-web-toolkit-contributors/CAN%3DyUA0Wr0pWKUcqyN2YMkuoZZK7b3e-ipm7jqv2DdDeqk8sMA%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "GWT Contributors" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to [email protected] 
>> <javascript:>.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/google-web-toolkit-contributors/651f6423-853c-4c25-9b92-86d8ab711067%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/google-web-toolkit-contributors/651f6423-853c-4c25-9b92-86d8ab711067%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>> For more options, visit https://groups.google.com/d/optout.
>>
>

-- 
You received this message because you are subscribed to the Google Groups "GWT 
Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/google-web-toolkit-contributors/dfe8b1da-5547-4fb4-812b-73c8f14257a3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to