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 <sup...@bpilotglobal.com <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 <
>>>> google-web-toolkit-contributors@googlegroups.com> 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 <t.br...@gmail.com> 
>>>>> 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 
>>>>>> google-web-toolkit-contributors+unsubscr...@googlegroups.com.
>>>>>> 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 
>>>>> google-web-toolkit-contributors+unsubscr...@googlegroups.com.
>>>>> 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 google-web-toolkit-contributors+unsubscr...@googlegroups.com 
>> <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 google-web-toolkit-contributors+unsubscr...@googlegroups.com.
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