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.

Reply via email to