1

So, we are trying to use JsInterop so that in our GWT application, we can use some modules created externally in JavaScript.

We have an interface that have some contract, some methods that must be implemented by all views.

For example:

package com.foo;

import jsinterop.annotations.JsPackage;
import jsinterop.annotations.JsType;

@JsType(namespace = JsPackage.GLOBAL) 
public interface MyView {

    void doSomething();
    void doSomethingElse();
    Element getElement();   
}

Now imagine that in the JS side, we have the implementation of that interface:

export class MyViewImplementation extends window.$wnd.MyView {

  constructor() {
    super();
  }

  doSometing() {
    //Implementation goes here
  }

  doSomethingElse() {
    //Implementation goes here
  }

  getElement() {
    var div = document.createElement("div");
    div.textContent = "External Component Test";
    return div;
  }
}

Can this work? Currently, I have an error which says: Class extends value undefined is not a constructor or null

micgala
  • 86
  • 6
  • I believe you want to use `@JsType(isNative = true, namespace = JsPackage.GLOBAL)`. Take a look at the section "Importing a type from an external JavaScript script" here: http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJsInterop.html – TrogDor Apr 30 '20 at 13:38
  • If I use isNative = true, then my GWT application won't compile. The reason is that that interface is also implemented by my Java views, so it must not be marked with isNative... – micgala Apr 30 '20 at 13:50
  • 1
    What does it mean in JS to use `extends` with an interface? In JS, unless I'm mistaken, there aren't real interfaces, but instead interfaces represent a convention that must be followed, right? As such, to "implement an interface" in JS, you just need to declare those methods, and not actually export anything, right? – Colin Alworth Apr 30 '20 at 15:07

1 Answers1

0

Based on your feedback to my comment, I would remove @JsType from your interface and introduce a class with @JsType(isNative=true) that implements the interface.

public interface MyView {

    void doSomething();
    void doSomethingElse();
    Element getElement();   
}

public class JavaView implements MyView {
    // . . .
}

@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public class JsView implements MyView {

    @Override
    public native void doSomething();

    @Override
    public native void doSomethingElse();

    @Override
    public native Element getElement();   
}

Then in JavaScript:

export class JsView {
    // . . .
}
TrogDor
  • 984
  • 6
  • 14
  • Thanks! We ended up doing something like that, so, creating a new class which implements that interface, and exposing that class with @JsType instead than doing that on the actual interface. – micgala May 06 '20 at 14:42