In the Native JsTypes section here 
<https://docs.google.com/document/d/10fmlEYIHcyead_4R1S5wKGs1t2I7Fnp_PaNaa7XTEk0/edit?tab=t.0#heading=h.b1boa8c235km>,
 
they have the example:

@JsType(isNative = true)

public interface Foo {

  int getFoo();

}

Which doesn't have the JsProperty annotation.  Oddly, it then tells you to 
read the section "*Property setters & getters*" which tells you that you 
should put it on.

I'm going to put it on.  I've no clue how it works without it.

On Tuesday, 14 January 2025 at 9:39:28 am UTC+11 Jens wrote:

> Interesting. As far as I know it should not have worked. Your above 
> example should map to JavaScript:
>
> { getUsername: function() { .... }, getProfilePictureUrl: function() { 
> .... } }
>
> At the bottom of the jsinterop page there is a link to the JsInterop spec: 
> https://docs.google.com/document/d/10fmlEYIHcyead_4R1S5wKGs1t2I7Fnp_PaNaa7XTEk0/edit
>
> It states that you need @JsProperty in that case. GWT compiler must know 
> if it should treat the interface method as method or as property.
>
> -- J.
>
> Craig Mitchell schrieb am Montag, 13. Januar 2025 um 23:02:07 UTC+1:
>
>> Thanks again Thomas,
>>
>> Yep, getters worked.  I thought I tried this previously, but obviously 
>> not.
>>
>> I didn't need the JsProperty annotation. maybe because the interface is 
>> marked as native:
>>
>> @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL)
>> public interface CrazyGamesUser {
>>   String getUsername();
>>   String getProfilePictureUrl();
>> }
>>
>> I'll update 
>> https://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJsInterop.html 
>> to mention this is how you access attributes using JsInterop.
>>
>> Cheers.
>>
>> On Tuesday, 14 January 2025 at 4:19:36 am UTC+11 Thomas Broyer wrote:
>>
>>> On Monday, January 13, 2025 at 10:14:33 AM UTC+1 
>>> [email protected] wrote:
>>>
>>> Hi Thomas,
>>>
>>> Can an interface have attributes?  I thought interfaces can only have 
>>> methods?
>>>
>>>
>>> Yes, you'd have to make them getters (probably need to annotate them 
>>> with @JsProperty too)
>>>  
>>>
>>> So if I make it:
>>>
>>> @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL)
>>> public interface CrazyGamesUser {
>>> }
>>>
>>> I can't see how I can add the attributes:
>>>
>>> public String username;
>>> public String profilePictureUrl;
>>>
>>> ?
>>>
>>> Thanks again.
>>>
>>> On Monday, 13 January 2025 at 7:03:43 pm UTC+11 Thomas Broyer wrote:
>>>
>>> Use an interface rather than a class.
>>>
>>> See the note about castability in the javadoc: 
>>> https://javadoc.io/doc/com.google.jsinterop/jsinterop-annotations/latest/jsinterop/annotations/JsType.html
>>>
>>> Rule of thumb is: use a class only if it maps to a "constructor" in JS, 
>>> i.e. something you'll either create an instance of, or use in an 
>>> "instanceof" check; for everything else (generally something you get from 
>>> another API or "receive" in a callback), use an interface.
>>>
>>> In this case, I think you could also use name="Object".
>>>
>>> On Monday, January 13, 2025 at 7:47:28 AM UTC+1 [email protected] 
>>> wrote:
>>>
>>> Overlay types do work, and make it a little better:
>>>
>>> public class CrazyGamesUser extends JavaScriptObject {
>>>   protected CrazyGamesUser() {}
>>>   public final native String getUserName() /*-{ return this.username; 
>>> }-*/;
>>>   public final native String getProfilePictureUrl() /*-{ return 
>>> this.profilePictureUrl; }-*/;
>>> }
>>>
>>> However, it would be great if JsInterop just worked, so I could just do:
>>>
>>> @JsType(isNative = true, namespace = JsPackage.GLOBAL)
>>> public static class CrazyGamesUser {
>>>   public String username;
>>>   public String profilePictureUrl;
>>> }
>>>
>>> Maybe I'm missing something?
>>> On Monday, 13 January 2025 at 4:02:40 pm UTC+11 Craig Mitchell wrote:
>>>
>>> I'm calling some existing JS that returns a JS Object which I've 
>>> implemented in JsInterop:
>>>
>>> @JsType(isNative = true, namespace = "window.CrazyGames.SDK")
>>> public static class JsUser {
>>>     public native Promise<CrazyGamesUser> getUser();
>>> }
>>>
>>> I can happily call it:
>>> sdk.user.getUser()
>>>   .then(user -> {
>>>     // Do something with the user
>>>     return null;
>>>   })
>>>   .catch_(error -> {
>>>     return null;
>>>   });
>>>
>>> This issue is I'm struggling to work out how to define the return object 
>>> "CrazyGamesUser".  The actual JS object is just this:
>>> {
>>>     "username": "SingingCheese.TLNU",
>>>     "profilePictureUrl": "
>>> https://images.crazygames.com/userportal/avatars/4.png";
>>> }
>>>
>>> If I define it like this:
>>>
>>> @JsType(isNative = true, namespace = JsPackage.GLOBAL)
>>> public static class CrazyGamesUser {
>>>   public String username;
>>>   public String profilePictureUrl;
>>> }
>>>
>>> I get a java.lang.ClassCastException.
>>>
>>> So if I set the name to "?":
>>>
>>> @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL)
>>> public static class CrazyGamesUser {
>>>   public String username;
>>>   public String profilePictureUrl;
>>> }
>>>
>>> Then I get a compile error:
>>> '?' can only be used as a name for native interfaces in the global 
>>> namespace.
>>>
>>> But if I make it an interface, I can't have the member variables.
>>>
>>> If I do remove the member variables, it does work, and I can access them 
>>> via some JSNI:
>>>
>>> public static native String getUsername(CrazyGamesUser instance) /*-{
>>>   return instance.username;
>>> }-*/;
>>>
>>> But that's really ugly.  What's the correct approach here?
>>>
>>> Thanks.
>>>
>>>

-- 
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 view this discussion visit 
https://groups.google.com/d/msgid/google-web-toolkit/ff59fcdd-ba6e-4592-8bd0-2eea1be02ed7n%40googlegroups.com.

Reply via email to