NodeList and JsArrayList.asArray

150 views
Skip to first unread message

Colin Alworth

unread,
Jul 23, 2017, 11:18:46 PM7/23/17
to GWT Contributors
Using GWT 2.8.1, I'm trying to iterate through items found via a query selector:

Arrays.asList(document.querySelectorAll("button.with-some-class").asArray()).forEach(
        item
-> doSomething(item)
);

Unfortunately, this seems to always fail - querySelectorAll returns a NodeList<Element>, and while asArray() seems to specify Js.uncheckedCast, the resulting generated code is

$forEach_1(new Arrays$ArrayList(castToJsArray(($clinit_DomGlobal() , document_0).querySelectorAll('button.with-some-class'))), new SampleClass$lambda$0$Type);

Predictable, the bolded castToJsArray causes an exception at runtime, since a NodeList isn't actually a JS Array at all.

Is there a correct way to do this, or perhaps a nicer way to iterate through NodeLists?

I assume this should be a bug filed against jsinterop-base, but am not seeing a repo for it, or is this a bug in GWT itself?

Goktug Gokdogan

unread,
Jul 24, 2017, 6:12:04 PM7/24/17
to google-web-toolkit-contributors
For following code:

class A<T> {
  T[] asArray {}..
}

A<String> st;
String[] arr = st.asArray();

I wasn't expecting an erasure cast at the call site for this but seems like I was wrong and erasure cast seems right here otherwise you cannot guarantee that arr[0] which won't have a cast to return String.

We should be able to repro this in jsinterop.base; will take a look.


--
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+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/4764126b-ed92-409a-bb4b-d1d1fead2e3c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Goktug Gokdogan

unread,
Jul 31, 2017, 1:45:24 PM7/31/17
to google-web-toolkit-contributors
It is fixed internally. asArray API replaced with asList API

On Mon, Jul 24, 2017 at 3:11 PM, Goktug Gokdogan <gok...@google.com> wrote:
For following code:

class A<T> {
  T[] asArray {}..
}

A<String> st;
String[] arr = st.asArray();

I wasn't expecting an erasure cast at the call site for this but seems like I was wrong and erasure cast seems right here otherwise you cannot guarantee that arr[0] which won't have a cast to return String.

We should be able to repro this in jsinterop.base; will take a look.

On Sun, Jul 23, 2017 at 8:18 PM, Colin Alworth <nilo...@gmail.com> wrote:
Using GWT 2.8.1, I'm trying to iterate through items found via a query selector:

Arrays.asList(document.querySelectorAll("button.with-some-class").asArray()).forEach(
        item
-> doSomething(item)
);

Unfortunately, this seems to always fail - querySelectorAll returns a NodeList<Element>, and while asArray() seems to specify Js.uncheckedCast, the resulting generated code is

$forEach_1(new Arrays$ArrayList(castToJsArray(($clinit_DomGlobal() , document_0).querySelectorAll('button.with-some-class'))), new SampleClass$lambda$0$Type);

Predictable, the bolded castToJsArray causes an exception at runtime, since a NodeList isn't actually a JS Array at all.

Is there a correct way to do this, or perhaps a nicer way to iterate through NodeLists?

I assume this should be a bug filed against jsinterop-base, but am not seeing a repo for it, or is this a bug in GWT itself?

--
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+unsu...@googlegroups.com.

Vassilis Virvilis

unread,
Aug 2, 2017, 8:41:13 AM8/2/17
to google-web-tool...@googlegroups.com
Can you expand a little bit on this? Are there any consequences we need to look for?

Is there a commit to look at?


For more options, visit https://groups.google.com/d/optout.



--
Vassilis Virvilis

Goktug Gokdogan

unread,
Aug 2, 2017, 1:01:36 PM8/2/17
to google-web-toolkit-contributors
Unfortunately jsinterop.base doesn't have github repo available yet so you can't see the commut.

Change is asArray method is replaced with asList that looks like this:
  @JsOverlay
  default List<T> asList() {
    // Since it is hidden behind Arrays.asList, it is safe to do uncheckedCast.
    T[] asArray = Js.uncheckedCast(this);
    return Arrays.asList(asArray);
  }

On Wed, Aug 2, 2017 at 5:41 AM, Vassilis Virvilis <vas...@gmail.com> wrote:
Can you expand a little bit on this? Are there any consequences we need to look for?

Is there a commit to look at?



--
Vassilis Virvilis

--
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+unsubscribe@googlegroups.com.

Tony BenBrahim

unread,
Aug 2, 2017, 8:01:19 PM8/2/17
to GWT Contributors

In my opinion, there is too much effort put in making Array behave like a normal Java class when it is not. There are already plenty of good options in GWT/Java for collections, arrays, etc…
A JavaScript Array is not equivalent to T[], for example this is a perfectly fine JavaScript Array [1,2,3,"abc", true, {x:1, y:2}] and cannot be modeled in Java. In my opinion, Array should maintain its JavaScript nature.

For example if the from method actually returned an Array like it does in JavaScript:

public static Array from(JsArrayLike arrayLike);

instead of

public static final <T, R> R[] from(JsArrayLike<T> arrayLike);

then Colin could write

Array.from(document.querySelectorAll("...")).forEach(element-> ...);

which looks exactly what you would write in JavaScript, and you would not have to implement toArray and toList on JsArrayLike, which is not mandated by the spec (the only requirement for ArrayLike is an indexed getter and the length attribute) Unfortunately,as it is currently, you cannot chain to other Array methods when T[] is the return type.

I do understand the desire for asList(), because in JavaScript, I might also write

for (elem in document.querySelectorAll(...){
...
}

but implementing Iterable would be a more desirable solution if possible.

Reply all
Reply to author
Forward
0 new messages