On Tuesday, August 29, 2017 at 12:36:11 PM UTC+2, zakaria amine wrote:
>
> Hello,
>
> This is a minor remark, and it does affect the functioning of JsInterop,
> as far as I experienced, but may be worth looking into by GWT folks. I have
> the following Js object that I am wrapping in Java:
>
> var Hotel = function() {
> this.guests = [];
> };
>
>
> Hotel.prototype = {
> addGuest : function(guest) {
> this.guests.push(guest);
> },
> getGuestCount: function(){
> return this.guests.length;
> }
> }
>
>
> @JsType(isNative=true, namespace=GLOBAL)
> public class Hotel {
> @JsMethod
> public native final int getGuestCount();
>
> @JsMethod
> public native final void addGuest(Guest guest);
> }
>
> I pass a Guest object to the addGuest Method
>
> @JsType(isNative=true, namespace=GLOBAL, name="Object")
> public class Guest {
>
> public int guestId;
>
>
> public String firstName;
>
>
> public String lastName;
>
> public String roomNumber;
> }
>
>
> public class Test implements EntryPoint {
>
>
> String uninitializedString;
>
> public void onModuleLoad() {
>
>
> Hotel hotel = new Hotel();
>
>
> Guest guest = new Guest();
> guest.firstName= "test";
> //passed object is guest = {firstName: "test"}
> hotel.addGuest(guest);
>
>
> Guest guest2 = new Guest();
> guest2.firstName = "test";
> guest2.lastName = uninitializedString;
> //passed object is guest = {firstName: "test", lastName: undefined},
> should also be guest = {firstName: "test"}
> hotel.addGuest(guest2);
> }
>
> }
>
>
> In short, if you are assigning an uninitialized variable to an
> uninitialized Object field, the field will not be ignored anymore by
> JsInterop, and will be transpiled as undefined, although it is still
> uninitialized. This happens often with the builder pattern.
>
Let's translate your code to JS manually:
let uninitializedString;
function onModuleLoad() {
let hotel = new Hotel();
let guest = new Object(); // because you used name="Object"; at that
point, guest is {}
guest.firstName = "test";
hotel.addGuest(guest);
let guest2 = new Object();
guest2.firstName = "test";
guest2.lastName = unitializedString;
hotel.addGuest(guest2);
}
See? your property assignments are creating the properties on a bare JS
Object, and assigning 'undefined' will still create the property.
Also keep in mind that what you declare in your native types are only
mapping about how to use/call the JS API, not necessarily what it actually
is under the hood; i.e. just because you use a field does not mean that
it's actually a "simple" JS property: it could have been defined with a
setter, so guest2.lastName=undefined might actually have a side-effect
other than creating a property (that's exactly that kind of property that's
declared when you use getter/setter methods for a @JsProperty in a
non-native type); and conversely, you could use getter/setter methods for a
@JsProperty in a native type, that's a "simple" property in JS.
BTW, the 'undefined' here is seen by GWT as a Java 'null', but it won't
bother initializing the field with 'null' as it treats 'undefined' and
'null' as equivalent (to a Java 'null'); this is an optimization technique
(saves a few bytes in generated payload, and CPU cycles at runtime) that
IIRC was added at some point in the GWT 2 lifecycle; earlier versions would
explicitly initialize the uninitializedString field to null in the Test
constructor/initializer.
--
You received this message because you are subscribed to the Google Groups "GWT
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.