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/efd4a74a-9f08-4b5a-a063-1af5df606bf4n%40googlegroups.com.

Reply via email to