In dart how to extend a custom PolymerElement with PaperInputBehavior? - dart

Basically I try to do a port of GoldCcCvcInput to a dart implementation, instead of wrapping of a js implementation.
Looking at this:
https://github.com/PolymerElements/gold-cc-cvc-input/blob/master/gold-cc-cvc-input.html
Together with https://github.com/dart-lang/polymer-dart/wiki/behaviors
Something like:
#PolymerRegister('nbdate-input')
class NbdateInput extends PolymerElement with PaperInputBehavior,
IronControlState, IronA11yKeysBehavior ...
Minimal test project
https://github.com/jonboj/inputbehavior-dart.git
The project initialize without dumping any error messages and displays the iron-input elements ok. But when one of the iron-input elements are put in focus, the exception below is dumped in the console:
Uncaught TypeError: Cannot read property 'focus' of undefined
Polymer.PaperInputBehaviorImpl._onFocus
handler
Polymer.Base._addFeature.fire
Polymer.IronControlState._focusBlurHandler
This has an override of method onFocusedChanged https://github.com/PolymerElements/gold-cc-cvc-input/blob/master/gold-cc-cvc-input.html#L219
In dart a corresponding Observer is triggered, with a printout occurring after the exception dump.
https://github.com/jonboj/inputbehavior-dart/blob/master/lib/nbdatebehavior_input.dart#L56

I would check the console for errors, the mixin ordering doesn't look like it is correct and it should give you the desired ordering in a message, which may solve your issue (I would expect an ordering like this IronA11yKeysBehavior, IronControlState, PaperInputBehavior).
Additionally, make sure you are calling polymerCreated() in your constructor.

For my case the needed functionality was provided by
https://elements.polymer-project.org/elements/paper-input?active=paper-input-container
With Dart following the structure of last example (Social Security Number) in
https://elements.polymer-project.org/elements/paper-input?view=demo:demo/index.html&active=paper-input

Related

Calling a static method from Thymeleaf TEXT template - how to bypass the Restricted mode

Is it possible to call a static method from a Thymeleaf textual template?
Official guide mentions that it should be possible to call a method like this:
<p th:text="${#myapp.translator.Translator#translateToFrench(textVar)}">Some text here...</p>
When I try to use it in my textual template (TemplateResolver's mode is set to TemplateMode.TEXT), I get a this exception:
org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating OGNL expression: "#java.lang.System#currentTimeMillis()" (template: "template.txt" - line 1, col 18)
Here is my sample template:
System millis: [(${#java.lang.System#currentTimeMillis()})]
After googling for a while, I also found this form of calling methods:
System millis: [(${T(java.lang.System).currentTimeMillis()})]
which fails with the same error.
What I need to do is somehow allow usage of a custom number formatter class from a template (functionality of the #numbers utility object is not rich enough for my case).
I can call methods on a non-static class by providing it as a context variable like this:
Some value: [(${formatter.format(someValue)})]
but it would be easier for me to use a static class without a need to explicitly adding it to each template's context.
BTW, I do not use Spring, just pure Thymeleaf.
Update
I should've spend more time to analyze the stack trace of the Thymeleaf exception I got.
It turns out, that the root cause of this behavior was the org.thymeleaf.exceptions.TemplateProcessingException: Instantiation of new objects and access to static classes is forbidden in this context exception, which is results from this change: https://github.com/thymeleaf/thymeleaf/issues/809
Downgrading to Thymeleaf 3.0.11 "fixes" it.
Now I'm looking for a solution to bypass this new Resctricted mode on the latest Thymeleaf (3.0.12 for the moment). I'm sure it's safe in my case, because I'm the only author of both code and templates.
An alternative would be to use the th:with attribute. It's a little more verbose, but still should allow you the same flexibility. (This works for me on 3.0.12.RELEASE.)
[# th:with="time=${#java.lang.System#currentTimeMillis()}"]System millis: [[${time}]][/]
https://github.com/thymeleaf/thymeleaf/issues/816#issuecomment-826401631 has extensive info on why this was done and possible workarounds. In your case, it will be best to add a model attribute in your controller and use that instead of calling the static method in the template.
#Controller
public class MyController {
public String myControllerMethod(Model model) {
model.addAttribute("time", System.currentTimeMillis());
return "name-of-the-thymeleaf-template";
}
}
and update your template to use:
System millis: [(${time})]

No compile time error in Dart when a method is given a parent class in place of its subclass

The following gives a runtime error on the last line but why do I not receive a compile time error?
Why is this? fnSub (last line) accepts a type of Sub but here I'm passing it a type of Parent and it compiles. Ok, I do get a runtime error but I'd have thought this should have given me a compile time error. Is this a bug in Dart or am I misunderstanding the limitations of the type system or have I just gone crazy?
class Parent {}
class Sub implements Parent {
String get blah => "blah";
}
String fnSub(Sub sub) => sub.blah;
String aProblem(Parent parent) => fnSub(parent);
https://dartpad.dev/acd2767cd42371deae0644fa66e8c602
The problem is that implicit-casts are enabled by default in Dart which is a feature trying to make it easier to work around types in Dart by automatically adding type casts in your code base.
This feature will no longer be available when NNBD (Non-nullable by default) are coming where implicit-dynamic also will be gone. Both features can already be disabled today by following this guide: https://dart.dev/guides/language/analysis-options#enabling-additional-type-checks
Personally, I think most projects should disable this two features already since I have seen a lot of people on Stackoverflow being confused about what Dart are doing with the types. So I cannot wait for NNBD so we can get are lot more clear type experience in Dart. And hopefully, the errors from the analyzer will be clear enough for most people so they don't need to get help.
If you disable implicit-casts you code will fail at the following line:
String aProblem(Parent parent) => fnSub(parent);
And with this error:
error - The argument type 'Parent' can't be assigned to the parameter type 'Sub'. - bin\stackoverflow.dart:9:41 - argument_type_not_assignable
If you want to test with Dartpad you can try with the following edition based on a beta version of the next Dart version which has enabled null-safety (and therefore have no implicit-casts): https://nullsafety.dartpad.dev/

Implement "GcmClient.Register(this, Constants.SenderID);" in non activity class

I am trying to implement receive/push azure notification with google cloud messaging in Android Xamarin project
I have followed "Get started with Notification Hubs with Xamarin for Android" article and everything went fine and I can receive notification!
in this article we add these lines of code in MainActivity class
GcmClient.CheckDevice(this);
GcmClient.CheckManifest(this);
GcmClient.Register(this, Constants.SenderID);
but we are going for some reason not use activity class, and I need to apply mentioned codes in none activity class ,
as the input "this" for above codes are "Android.Content.context"
,I tried to get Android.Content.context and send as parameter to CheckDevice and CheckManifest method
var _this = Android.App.Application.Context;
GcmClient.CheckDevice(_this);
GcmClient.CheckManifest(_this);
but i get following Error in "GcmClient.CheckManifest(_this);" line
I am quite new in this area but I guess i missing to add some info in manifest file, I really appreciate if you help me how we implement mentioned codes about GcmClient in non activity class in order to implement notification
Thanks
As stated in this forum, it is thrown by System.Reflection when the latter catches an exception, while attempting to query / manipulate / invoke one of the member of the instance reflected upon. Also based from this thread, "TargetInvocationException masks the real exception by telling you that it crashed during "a method invocation", usually through something.Invoke. What you have to do is look at the InnerException property of the exception object (the TargetInvocationException object), this will give you the actual exception that was thrown, with a more useful stack trace."

Passing an object reference to Dart script of Polymer Element

I am trying to pass an object reference to the Dart script associated with a Polymer element. I have found the element in the DOM but I can't figure out how to call a method in the Dart associated with the element or any other way to dynamically pass an object to the Polymer element to be displayed.
Basically you just get a reference by using for example querySelector('#someid') and just assign the value to a field or setter or call a method and pass it as an argument.
querySelector('#someid').someField = someValue;
querySelector('#someid').setValue(someValue);
This might produce a hint in DartEditor but should still work when the code is executed. To get rid of the hint you can "cast" like
(querySelector('#someid') as MyComponent).someField = someValue;
querySelector('#someid') as MyComponent).setValue(someValue);
You need to import MyComponent to make this work.
If this doesn't something with your code might be wrong. For example the main() method if you have one. See how to implement a main function in polymer apps for more details.
If nothing of the above works, please add code to your question that shows what you're trying to accomplish.

How do I access a non-#observable field via polymer bindings with dart2js in Dart?

Seth Ladd's Polymer.dart examples are awesome and really helpful. The observable_list example appends DateTime instances to an ObservableList timestamps. Although DateTime does not extend Observable, modifying my_element.html to access a field on
{{ts in timestamps}}
works when running in the Dart VM. For example, changing
<li>{{ts}}</li>
to
<li>{{ts.second}}</li>
will access the DateTime.seconds field when on the Dart VM. However, when dart2js compiles the app to javascript, access to fields in the Polymer expression is broken. An exception Uncaught Error: RangeError: value 0 is thrown in this case, or more generally NoSuchMethodError : method not found: 'Symbol(...)' for the fieldname is thrown (see example here)
If a class extends Observable then access to #observable fields works inside of Polymer expressions after compiling to Javascript (changing the class MyRow in this example to extends Observable does not throw an exception in javascript).
What can I do when I am unable to add annotations to external classes like DateTime? Is this just a current bug in dart2js generation, or will the Polymer.dart spec forbid reading fields out of non-observable classes? Previously, web_ui successfully accessed fields from our dart-protobuf generated classes after compiling to javascript, so I'm hoping this use-case will gain support in Polymer.dart too.
In general, dart2js tries to tree-shake and minify code, and it doesn't know that some of the code is used from a polymer expression (which uses mirrors internally to interpret the expressions). Very likely what happened here is that dart2js is either deleting the non-observable fields or minifying them in a way that they are not reflectable.
To fix this, you can indicate that these fields need to be preserved and used via mirrors. In polymer we provide the #reflectable annotation for this purpose. (#observable also implies #reflectable, that's why it works when you have #observable). So you can use that in the MyRow case.
Fields from types in the core libraries can work also if they become reflectable. In this case it is a bit harder to express because you can't modify the original code to add this annotation. Instead you can use the #MirrorsUsed annotation to override the default behavior on these core types, or avoid using these fields inside polymer-expressions by hiding them inside #reflectable getters or in filters that are written directly in Dart code.

Resources