I am trying to migrate from using compiler flag -XjsInteropMode JS but I run into a problem.
I have an interface called Module that looks like this:
#JsType
public interface Module {
#JsProperty
String getBasename();
}
Then I have another interface called AuthenticationModule which looks like this:
#JsType
public interface AuthenticationModule extends Module {
static final String MODULE_NAME = "authentication";
void logIn(String username, String password, JsConsumer<JavaScriptObject> onSuccess, JsConsumer<JavaScriptObject> onError);
void logOut(JsConsumer<JavaScriptObject> onSuccess, JsConsumer<JavaScriptObject> onError);
}
The module interface is just a marker interface, so when I was loading some module, I was able to cast it in the end to a module I wanted, example here:
#Override
public void getAuthenticationModule(
OnModuleLoaded<AuthenticationModule> onModuleLoaded) {
initializeIfNecessary();
JsArrayString requiredModules = JavaScriptObject.createArray().cast();
requiredModules.push(AuthenticationModule.MODULE_NAME);
modules.require(requiredModules, loadedModule -> {
onModuleLoaded.moduleLoaded((AuthenticationModule) loadedModule); // this line (the casting) throws ClassCastException
});
}
modules in this code is another interface which looks like this:
#JsType
public interface Modules {
#JsFunction
#FunctionalInterface
interface CallbackRequire {
void apply(Module module);
}
#JsProperty
String getBase();
#JsProperty
void setBase(String base);
void require(JsArrayString modules, CallbackRequire onload);
}
I followed the rules on how to migrate in this document:
https://docs.google.com/document/d/10fmlEYIHcyead_4R1S5wKGs1t2I7Fnp_PaNaa7XTEk0/edit#
I was not able to solve this issue. The best I could get was changing #JsType to #JsType(isNative = true). Then the casting was working, but another error occured, can't remember now, but I'm not sure if the isNative is really the right way to solve this issue.
After adding "(isNative = true)" to most of the interfaces, it all works again. The only thing I had to change were the MODULE_NAME fields, since they cannot be initialized in a native JsType.
Related
I'm using sanitizer.bypassSecurityTrustUrl to put links to blobURL's on the page. This works just fine as long as I don't AoT compile the project.
import {DomSanitizer} from '#angular/platform-browser';
export class AppComponent {
constructor(private sanitizer: DomSanitizer) {
}
sanitize(url: string) {
return this.sanitizer.bypassSecurityTrustUrl(url);
}
}
The sanitize function takes a URL like this:
blob:http://localhost:4200/7c1d7221-aa0e-4d98-803d-b9be6400865b
If I use AoT compilation I get this error message:
Module build failed: Error: /.../src/app/app.component.ts (18,3):
Return type of public method from exported class has or is using name
'SafeUrl' from external module
"/.../node_modules/#angular/platform-browser/src/security/dom_sanitization_service"
but cannot be named.)
I'm using CLI with Angular 2.1.0
Anybody knows how I can circumvent this problem? Or should it be reported as a bug?
So it seems I had to add a return type of SafeUrl to the method
sanitize(url: string):SafeUrl {
return this.sanitizer.bypassSecurityTrustUrl(url);
}
Big thanks to alxhub
In my case i was initiating an attribute like this :
public img64 = this.domSanitizer.bypassSecurityTrustResourceUrl('data:image/jpg;base64,' + this.base64Image);
Resulting in the same error.
Thanks to #mottosson I got it right (just add the type SafeUrl):
public img64: SafeUrl = this.domSanitizer.bypassSecurityTrustResourceUrl('data:image/jpg;base64,' + this.base64Image);
I have defined the following two function signatures in the same Typescript class, i.e.,
public emit<T1>(event: string, arg1: T1): void {}
and
public emit<T1,T2>(event: string, arg1: T1, arg2: T2): void {}
However when transpiling the typescript I get the following error
error TS2393: Duplicate function implementation.
I thought you could overload functions in typescript providing the number of parameters in the function signature were different. Given that the above signatures have 2 and 3 parameters respectively, why am I getting this transpilation error?
I'm assuming your code looks like this:
public emit<T1>(event: string, arg1: T1): void {}
public emit<T1,T2>(event: string, arg1: T1, arg2: T2): void {}
public emit(event: string, ...args: any[]): void {
// actual implementation here
}
The problem is that you have {} after the first 2 lines. This actually defines an empty implementation of a function, i.e. something like:
function empty() {}
You only want to define a type for the function, not an implementation. So replace the empty blocks with just a semi-colon:
public emit<T1>(event: string, arg1: T1): void;
public emit<T1,T2>(event: string, arg1: T1, arg2: T2): void;
public emit(event: string, ...args: any[]): void {
// actual implementation here
}
export {}
Just add this line at the top of the typescript file
Because you open both Typescript and JavaScript file in the same window in IDE you can solve this problem with three ways:
First Solution:
Open typescript file only or JavaScript file only
Second solution - run this command:
tsc --init
This command will create tsconfig.json file for typescript configuration
Last Solution write
export{}
In the top of the file
VideoPlayerView is a custom native component made in Android and IOS for my particular project.
Here is a part of code exporting native module named VideoPlayerView made by ReactVideoManager.java
public class ReactVideoManager extends SimpleViewManager<MeasureChangedVideoView> {
public static final String REACT_CLASS = "VideoPlayerView";
private ThemedReactContext mReactContext;
#Override
public String getName() {
return REACT_CLASS;
}
#Override
protected MeasureChangedVideoView createViewInstance(ThemedReactContext reactContext) {
mReactContext = reactContext;
return new MeasureChangedVideoView(reactContext);
}
#ReactProp(name = "url")
public void setUrl(MeasureChangedVideoView view, #Nullable String url) {
Uri uri = Uri.parse(url);
view.setVideoURI(uri);
view.setMediaController(new MediaController(mReactContext));
view.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
}
}
Below is the error log found for the module:
Error: `VideoPlayer` has no propType for native prop `VideoPlayerView.scaleY` of native type `number`
The corresponding js component for this native view is VideoPlayer.js:
var React = require('react-native');
var { requireNativeComponent } = React;
class VideoPlayer extends React.Component {
render() {
return <VideoPlayerView {...this.props} />;
}
}
VideoPlayer.propTypes = {
url: React.PropTypes.string
};
var VideoPlayerView = requireNativeComponent('VideoPlayerView', VideoPlayer);
module.exports = VideoPlayer;
The very same module used to work in a different project B. The only difference found was presence of a react.gradle file in project B.
There is absolutely no clue where react.gradle file is generated. Also I tried restarting packager, cleaning the project building again.
The gradle dependency used in project is
compile "com.facebook.react:react-native:0.14.+"
One should definitely use the latest version and the way specified in docs https://facebook.github.io/react-native/docs/native-components-android.html#content should work fine.
So It turns out that I was using React version 0.13+ (in package.json) and the way of adding properties using #Reactprop annotation was introduced in gradle 0.14 dependency and this way doesn't quite work well with the older version of React-native(0.13).
If due to some reason you happen to work on 0.13 or pre, the way of mixing in of props manually as specified in https://github.com/facebook/react-native/issues/3478 must be followed.
I am tasked to compile the gwt project(which doesnot include HTML CSS) into JS files and add the same to an external JS/HTML file( which is in different project).
here is the java code which has to be compiled:
1. Client class:
package com.dell.supportassist.gwt.collectionReport.client;
import org.timepedia.exporter.client.Export;
import org.timepedia.exporter.client.Exportable;
#Export("HelloWorld")
public class HelloWorld implements Exportable {
public String sayHello(){
return "Hello";
}
}
EntryPoint Class:
package com.dell.supportassist.gwt.collectionReport.client;
import org.timepedia.exporter.client.Export;
import org.timepedia.exporter.client.Exportable;
#Export("HelloWorld")
public class HelloWorld implements Exportable {
public String sayHello(){
return "Hello";
}
}
My issue is, once the above gwt project/classes are complied, i want to access 'sayHello()' method in ma external javascript like this:
var person = hello.sayHello();
system.log(person);
But this is throwing a run time error saying 'hello' is not defined.
P.S I am trying to use the GWT compiled JS in an external HTML, JS Present in Durandaljs Framework.
Haven't done this kind of stuff for quite some time but you could achieve this using JSNI, which allows you to write native JS in GWT. From JSNI you can reference your GWT methods. That way you could define a function (on window, most typically) which would then become available to regular JS. From this JSNI-method you can reference your GWT/Java code.
Code example:
public class MyModule implements EntryPoint {
static {
export();
}
/**
* Makes our setData method accessible from plain JS
*/
private static native void export() /*-{
$wnd.setData = #my.package.MyModule::setData(Lcom/google/gwt/core/client/JavaScriptObject;);
}-*/;
private static void setData(JavaScriptObject javaScriptObject) {
// this method is now reachable as window.setData
}
}
I have a class library written in Java and want to convert it to Javascript. All methods are pretty simple and mostly have to do with manipulating collections. I have this one class, GameControl, which I could instantiate and I want its methods exposed to other Javascript code on the page.
I thought to use GWT. I have a running project in GWT which compiles, but I can't figure out how to expose my instance (+functionality) of the GameControl class.
I thought using JSNI to expose my object should work, but it didn't. This is the short version of how it look like right now:
GameEntryPoint.java
import com.google.gwt.core.client.EntryPoint;
public class GameEntryPoint implements EntryPoint {
private GameControl _gameControl;
#Override
public void onModuleLoad() {
_gameControl = new GameControl();
expose();
}
public native void expose()/*-{
$wnd.game = this.#game.client.GameEntryPoint::_gameControl;
}-*/;
}
GameControl.java
package game.client;
public class GameControl {
public boolean isEmpty(int id){
// does stuff...
return true;
}
}
So, GWT indeed compiles the code, and I see that there is a GameControl_0 object being built and set into $wnd.game, but no isEmpty() method to be found.
My expected end result is to have a window.game as an instance of GameControl with all public methods GameControl exposes.
How can I do this?
Edit
As per #jusio's reply, using JSNI to expose window properties explicitly worked, but it was too verbose. I'm trying the gwt-exporter solution. Now I have
GameEntryPoint.java
package game.client;
import org.timepedia.exporter.client.ExporterUtil;
import com.google.gwt.core.client.EntryPoint;
public class GameEntryPoint implements EntryPoint {
#Override
public void onModuleLoad() {
ExporterUtil.exportAll();
}
}
RoadServer.java
package game.client;
import org.timepedia.exporter.client.Export;
import org.timepedia.exporter.client.ExportPackage;
import org.timepedia.exporter.client.Exportable;
#ExportPackage("game")
#Export("RoadServer")
public class RoadServer implements Exportable {
int _index;
int _id;
public RoadServer(int index,int id){
this._id=id;
this._index=index;
}
}
but still none of the code is exported (specifically not RoadServer).
You have exposed only instance of the GameControl. If you want to expose other methods, you'll have to expose them as well.
For example:
public native void expose()/*-{
var control = this.#game.client.GameEntryPoint::_gameControl;
var gameInstance = {
gameControl: control,
isEmpty:function(param){
control.#game.client.GameEntryPoint::isEmpty(*)(param);
}
}
$wnd.game = gameInstance;
}-*/;
Also there is a framework called gwt-exporter, it might make things easier for you
This may help.
http://code.google.com/p/gwtchismes/wiki/Tutorial_ExportingGwtLibrariesToJavascript_en