Using Dart JS interop with ES6 classes - dart

JavaSscript:
class MyClass {
constructor() {
console.log("MyClass instance created");
this.answer = 42;
}
}
let example = new MyClass();
console.log(example.answer);
Dart:
#JS()
library interop_test;
import 'package:js/js.dart';
#JS()
class MyClass {
external int get answer;
external set answer(int value);
}
Creating an instance of the the interop class MyClass as
MyClass myClass = MyClass();
results in:
EXCEPTION: TypeError: dart.global.MyClass is not a constructor
I've also tried to add a external MyClass(); and external factory MyClass(); to the #JS() annotated class, but got the same message. If I add #anonymous annotation to the interop class, the exception goes away, but I can't access instance members. (But I don't see why this would need the anonymous annotation)
I'm using dart 2.0.0, angular 5.0.0, js 0.6.1+1 and dartdevc through webdev.

Normally JS interop would rely on function hoisting to ensure that an old-style JS class was in scope. ES6 classes however aren't hoisted and aren't available where Dart expects them to be. There are several different ways you can make the class available to Dart:
Placing the class object on the window
This places the class in the same scope that a function definition would be hoisted to. In JavaScript:
class MyClass { ... }
window.MyClass = MyClass;
Creating a module object
You can also place the class in a sort of pseudo module or namespace. In JavaScript:
class MyClass { ... }
var myModule = { MyClass: MyClass };
Which is then accessible at myModule.myClass in Dart:
#JS('myModule.myClass')
class MyClass { ... }

Related

In Dart, how to access a parent private var from a subclass in another file?

I have two classes in Dart, MyClass1 and MyClass2 where MyClass2 extends MyClass1. In some of MyClass2 functions, I want to access a variable that has "private" access privileges in MyClass1.
If MyClass1 and MyClass2 are declared in the same dart file, like this:
class MyClass1 {
double _myprivatevar;
}
class MyClass2 extends MyClass1 {
MyClass2(double myvar){
this._myprivatevar = myvar;
}
}
everything is fine
But now, if MyClass2 is declared in its own dart file:
import 'package:test/myclass1.dart';
class MyClass2 extends MyClass1 {
MyClass2 (double myvar){
this._myprivatevar = myvar;
}
}
I have an error saying:
The setter '_myprivatevar' isn't defined for the class 'MyClass2'. Try
importing the library that defines '_myprivatevar', correcting the
name to the name of an existing setter, or defining a setter or field
named '_myprivatevar'.dart(undefined_setter)
how can I solve this issue and have access to a parent private variable from a subclass defined in another dart file?
You can use #protected annotation for this.
class MyClass1 {
double _myprivatevar;
#protected double get myprivatevar => _myprivatevar;
#protected set myprivatevar(newValue) {
_myprivatevar = newValue;
}
}
class MyClass2 extends MyClass1 {
MyClass2(double myvar){
myprivatevar = myvar;
}
}
Source and Github issue link
You cannot directly access a private name from a different library, and Dart does not have any privacy notation corresponding to "protected" (access from subclasses).
You have to either make the property public, declare the two classes in the same library, or not access the property from the subclass. There are no other options.
If your only issue is initializing an instance variable, then you could perhaps pass the value of the variable as a constructor argument to the superclass, thereby having the superclass access the variable for you:
class MyClass1 {
double _myPrivateVar;
MyClass1([double myPrivateValue]) : _myPrivateVar = myPrivateValue;
}
// In different library:
class MyClass2 extends MyClass1 {
MyClass2(double myVar) : super(myVar);
}
That won't help you read the private variable later, it's still only the superclass, and other code in the same library, which can access the variable.
you can use part/ part of
// lib.dart
library lib
part 'class1.dart'
part 'class2.dart'
// class1.dart
part of lib
// class2.dart
part of lib

Is it possible to have a private constructor in dart?

I'm able to do something like the following in TypeScript
class Foo {
private constructor () {}
}
so this constructor is accessible only from inside the class itself.
How to achieve the same functionality in Dart?
Just create a named constructor that starts with _
class Foo {
Foo._() {}
}
then the constructor Foo._() will be accessible only from its class (and library).
A method without any code must be something like this
class Foo {
Foo._();
}
Yes, It is possible, wanna add more information around it.
A constructor can be made private by using (_) underscore operator which means private in dart.
So a class can be declared as
class Foo {
Foo._() {}
}
so now, The class Foo doesn't have a default constructor
Foo foo = Foo(); // It will give compile time error
The same theory applied while extending class also, It's also impossible to call the private constructor if it declares in a separate file.
class FooBar extends Foo {
FooBar() : super._(); // This will give compile time error.
}
But both above functionality works if we use them in the same class or file respectively.
Foo foo = Foo._(); // It will work as calling from the same class
and
class FooBar extends Foo {
FooBar() : super._(); // This will work as both Foo and FooBar are declared in same file.
}
you can create following class in order to get a singleton instance
class Sample{
factory Sample() => _this ??= Sample._();
Sample._(); // you can add your custom code here
static Sample _this;
}
Now in the main function you can call the sample constructor
void main(){
/// this will return the _this instace from sample class
Sample sample = Sample();
}
just use abstract class.
Because you can't instantiate abstract class

How do I enforce injecting a specific instance, without access to the class impl code?

I'm trying to bind a class C from a third-party's package.
It injects a class Foo instance via constructor -
class C {
public C(#Inject Foo foo) {
...
}
...
}
In my application, I've two instances of Foo bound -
bind(Foo.class)
.to(FooImpl1.class);
bind(Foo.class)
.annotatedWith(Names.named("SpecialFoo"))
.to(FooImpl2.class);
when C is bound, I want the Named Foo instance to be used. However I do not have access to the code in which C is defined, to be able to put any annotations.
Is there a suggested way of doing that, short of writing my own provider method for C?
You could look into using PrivateModule. In your example, it will be something like:
public class CModule extends PrivateModule {
protected void configure() {
bind(Foo.class).to(FooImpl2.class);
bind(C.class);
expose(C.class);
}
}

Error Targeting Instance name from document class AS3

I have a document class with this function on it, it targets a symbol with an instance name of scene4_headlights on the stage:
function accUpdate(e:AccelerometerEvent):void{
scene4_headlights.rotation += (e.accelerationX*10);
}
But I keep getting error 1120: Access of undefined property scene4_headlights even though I have a symbol on the stage with the instance name of scene4_headlights..
Help?
Here you go:
package {
import flash.sensors.Accelerometer;
import flash.events.AccelerometerEvent; //importing everything you need is cruicial
import flash.display.MovieClip;
public class CustomClassName extends MovieClip //your custom class can extend the type of class you used to create your scene4_headlights instance (some prefer using Sprite when the timeline is not required)
{
private var accelerometer = new Accelerometer(); //declare a variable data type: Accelerometer
public function CustomClassName() {
// constructor code
accelerometer.addEventListener(AccelerometerEvent.UPDATE, accUpdate); // add an eventlistener to the variable you just created
}
public function accUpdate(e:AccelerometerEvent): void //declare the function handling the eventlistener
{
scene4_headlights.rotation += (e.accelerationX*10);
trace("The function accUpdate is linked properly"); //trace is your friend
}
}
}

Dart ClassMirror newInstance method says no such constructor

I tried to dynamically create a new instance of a class like this:
this.componentClass.newInstance(new Symbol(''), [this, el]).reflectee;
The class reflected in this.componentClass is called ButtonComponent and it is a subclass of Component. When running a test on this, I get an error:
Test failed: Caught No constructor 'ButtonComponent.' declared in class 'ButtonComponent'.
NoSuchMethodError : method not found: 'ButtonComponent.'
Receiver: Type: class 'ButtonComponent' Arguments: [...]
There are default constructors in both Component and ButtonComponent classes. Here is the code, to make sure I didn't miss anything:
class Component {
Element element ;
Template template;
Component(this.template, this.element) {
this.element.replaceWith(new Element.html(template.html));
}
}
class ButtonComponent extends Component {
ButtonComponent(template, element) : super(template, element) {};
}
Any ideas what is wrong here? Thank you.
I just made a similar test in 1.0.0.3_r30187 and I don't get this error. If you don't use the last stable version of Dart you should update your version.
Here's my tested code :
import 'dart:html';
import 'dart:mirrors';
class Component {
Element element ;
Component(this.element) {
this.element.children.add(new Element.html("<b>Dart rocks</b>"));
}
}
class ButtonComponent extends Component {
ButtonComponent(element) : super(element);
}
main() {
final a = reflectClass(ButtonComponent).newInstance(new Symbol(''),
[document.documentElement]).reflectee;
print(a); // display : Instance of 'ButtonComponent'
}

Resources