Dart data binding from a parent custom element to attributes of a child custom element - dart

Here is a problem that cropped up today when I updated to the latest Dart libs.
The child custom element is a combo box. The parent custom element fills it with a varying list of strings.
// child HTML
<polymer-element name="bx-icombo" attributes="aLabel aList aSelected">
<template>
<div class='outr' flex layout horizontal center>
<label for='inp' flex end-justified>{{aLabel}}</label>
<!-- wait until the data is available -->
<template if='{{aList}}'>
<paper-dropdown-menu id='inp' label='aLabel' valign='top' flex start-justified >
<paper-dropdown class="dropdown">
<core-menu id='m' class="menu" selected="{{aSelected}}">
<template repeat='{{aList}}'>
<paper-item name='{{}}'>{{}}</paper-item>
</template>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
</template>
</div>
</template>
<script type='application/dart' src='bx_icombo.dart'></script>
</polymer-element>
//---------------------------------------------------------------
// child Dart
#CustomTag('bx-icombo')
class BxICombo extends PolymerElement {
#PublishedProperty(reflect: true) String aLabel;
#PublishedProperty(reflect: true) List<String> aList;
#PublishedProperty(reflect: true) String aSelected;
BxICombo.created() : super.created();
}
//---------------------------------------------------------------
// Parent HTML
<polymer-element name="tst-sigs">
<template>
<paper-dialog backdrop heading='Sigs' closeSelector=''>
<bx-icombo aLabel='{{selectAsignal}}'
aList='{{sigsList}}'
aSelected='{{sigsSel}}'>
</bx-icombo>
</paper-dialog>
</template>
<script type='application/dart' src='tst_sigs.dart'></script>
</polymer-element>
//---------------------------------------------------------------
// Parent Dart
#CustomTag('tst-sigs')
class TstSigs extends PolymerElement {
#observable List<String> sigsList = ['alpha', 'beta', 'gamma'];
#observable String sigsSel;
#observable String selectAsignal = 'Select a Signal';
TstSigs.created() : super.created();
}
//---------------------------------------------------------------
Dartium reports:
Attributes on bx-icombo were data bound prior to Polymer upgrading the element. This may result in incorrect binding types. (:1)
So what has to be changed? #PublishedProperty or #observable or #published or .... I admit to finding the maze of #... annotations deeply unclear.
The versions are:
Dart: 1.9.3 (STABLE)
Dartium: 39.0.2171.99
and packages:
analyzer 0.24.6 (0.25.0+1 available)
args 0.12.2+6 (0.13.0 available)
barback 0.15.2+4
browser 0.10.0+2
cli_util 0.0.1+1
code_transformers 0.2.8
collection 1.1.0
core_elements 0.7.1+2
csslib 0.12.0
dart_style 0.1.8
glob 1.0.4
html 0.12.1+1
ini 1.1.0
initialize 0.6.0+4
intl 0.12.2
js 0.3.0
logging 0.9.3 (0.10.0 available)
markdown 0.7.1+2
matcher 0.11.4+4 (0.12.0-alpha.0 available)
observe 0.13.0+2
paper_elements 0.7.1
path 1.3.5
petitparser 1.3.7
polymer 0.16.1+4
polymer_expressions 0.13.1
polymer_interop 0.1.0+2
pool 1.0.1
quiver 0.21.3
smoke 0.3.2
source_maps 0.10.0+2
source_span 1.1.2
stack_trace 1.3.1
string_scanner 0.1.3+1
template_binding 0.14.0+2
utf 0.9.0+2
watcher 0.9.5
web_components 0.11.2
when 0.2.0
which 0.1.3
yaml 2.1.2
Initially a problem with code-transformers forced code_transformers < 0.2.5 and that limited polymer to 0.16.0. It looks as if the code transformer thing has been resolved so I have removed the version constraint and polymer updated to 0.16.1. The problem remains.
The main function is
import 'package:polymer/polymer.dart';
import 'lib/bxglobs/bxGlobs.dart' as G;
void realMain() {
// empty for this test
}
void main() {
G.initGlobals();
initPolymer().then((zone) => zone.run(() {
Polymer.onReady.then((_) => realMain());
}));
}
and pubspec.yaml:
name: bxPoly
description: BX GUI
dependencies:
core_elements: any
ini: any
intl: any
js: any
markdown: any
paper_elements: any
polymer: any
code_transformers: any
transformers:
- polymer:
entry_points:
- web/test.html

This error almost always occurs because of elements getting registered in the wrong order. Specifically, a parent element being registered before a child element.
This is hard to diagnose without full access to the code, but following these two rules should ensure its not an issue:
Put each polymer-element in its own html file, and each class in its own dart library (using parts especially causes issues).
Make sure your elements import all of their dependencies.

edit
<template if='{{aList != null}}'>
<paper-dropdown-menu id='inp' label='aLabel' valign='top' flex start-justified >
<paper-dropdown class="dropdown">
<core-menu id='m' class="menu" selected="{{aSelected}}">
<template repeat='{{a in aList}}'>
<paper-item name='{{a}}'>{{a}}</paper-item>
</template>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
original
If you bind from the shadow DOM of an element to its class #observable is enough.
If you want to bind to attributes from outside of an element use #published.
If you want to use the value of a bound attribute for example in CSS selectors use #PublishedAttribute(reflect: true). reflect means the properties value is reflected to the DOM, otherwise it's only available for Polymer and Dart code.
I haven't seen this error message before. Maybe there is a problem with Polymer initialization. Do you have a custom main? Can you add it to your question?
class MyA extends PolymerElement {
#observable
aobservable = 'obs';
#published
apublished = 'pub';
#PublishedAttribute(reflect: true)
areflected = 'ref';
}
<polymer-element name="my-a">
<template>
<!-- doesn't work
<my-b bobservable="{{aobservable}}"></my-b> -->
<my-b bpublished="{{aobservable}}"></my-b>
<my-b breflected="{{aobservable}}"></my-b>
<!-- you can bind properties of MyA here no matter if
they are observable/published/reflected
(even when they have no annotation but they will not
be updated when the value changes)
You can bind only to published (reflected or not)
attributes of MyB
-->
</template>
</polymer-element>
class MyB extends PolymerElement {
#observable
bobservable = 'obs';
#published
bpublished = 'pub';
#PublishedAttribute(reflect: true)
breflected = 'rep';
}
<polymer-element name="my-b">
<template>
</template>
</polymer-element>
<head>
<style>
// you can only address reflected attributes here
my-a[areflected="ref"] {
backgroundColor: red;
}
</style>
</head>
<body>
<my-a></my-a>
</body>

This seems to be the solution. Based on debugging rather than knowledge, so beware..
Say your component foo.dart and foo.html refers to another component bar.dart and bar.html. For instance, the reference might be:
barEl el = document.querySelector('bar');
Obviously you import bar.dart at the top of foo.dart. You get the error described unless you also
<link rel="import" href="bar.html">
at the top of foo.html. Even though bar.html is not conventionally referenced in foo.html.

Related

print statements in dart-polymer UI not seen in webstorm console

I have some print statements in a Dart UI app. Depending on the UI selection strings are printed to the console. Everything used to work as expected with with Dart with Eclipse plugin. Now I cannot see any print output to the console in my dart-polymer app.
Any possible help is appreciated.
EDIT 1
.dart
import 'dart:html';
import 'package:paper_elements/paper_input.dart';
import 'package:polymer/polymer.dart';
/// A Polymer `<main-app>` element.
#CustomTag('main-app')
class MainApp extends PolymerElement {
#observable String reversed = '';
/// Constructor used to create instance of MainApp.
MainApp.created() : super.created();
void reverseText(Event event, Object object, PaperInput target) {
reversed = target.value.split('').reversed.join('');
print(reversed); // NOTHING IS SHOWN IN ANY CONSOLE
}
.html
<!-- import polymer-element's definition -->
<link rel="import" href="../../packages/polymer/polymer.html">
<link rel="import" href="../../packages/paper_elements/paper_input.html">
<polymer-element name="main-app">
<template>
<style>
:host {
display: block;
}
</style>
<paper-input label="Type something..." on-keyup="{{reverseText}}"></paper-input>
<p>
Reversed: {{ reversed }}
</p>
</template>
<script type="application/dart" src="main_app.dart"></script>
</polymer-element>
The print statement in main_app.dart DOES NOT PRINT TO ANY VISIBLE CONSOLE.
Ensure you have the IntelliJ debug plugin installed in Dartium.
I had the same problem. Simply running the app (as in Dart Editor) does not seem to be enough. In WebStorm, the print() statements appear in Console as expected only when I run the app in debug-mode (Ctrl-d).

Dart Polymer: binding html files to scripts results in broken bootstrap.dart containing "%5C" characters

After doing a Pub Get and Pub Upgrade my custom-PolymerElements don't work anymore. It seems to me that the
<script type="application/dart" src="view.dart"></script>
is interpreted incorrectly. In my index.html_bootstrap.dart it is listed as: import 'dialog%5Cview.dart' as smoke_1; The "%5C" ( \ ) should be a slash ( / ) anyway and I'm pretty sure that it shouldn't be escaped. I tried it with the dart stable (1.8.5) and dev (1.9.0) versions for 64bit Windows.
I already tried to revert my package to their previous version but since I hadn't constraint them in my pubspec file I have no way to determine which versions worked before my changes. In another dart polymer project I'm working on I use the same setup (extended polymer elements) and it still works . The equivalent position in the index.html_bootstrap.dart reads: import 'dialog/view.dart' as smoke_1;
(edit) some (shortened) code:
/web/dialog/error/view.html
<link rel="import" href="packages/polymer/polymer.html">
<link rel="import" href="packages/paper_elements/paper_dialog.html">
<link rel="import" href="packages/core_elements/core_animated_pages.html">
<polymer-element name="error-view">
<template>
<style>
paper-dialog {
margin-top: 20px;
height: 400px;
width: 600px; }
</style>
<paper-dialog id="extendedNode" heading="{{dialogtitle}}" vertical autoCloseDisabled=true transition="paper-transition-center" opened=true>
<content>
<core-animated-pages selected="{{page}}" valueattr="id" transitions="hero-transition cross-fade">
<section id="0">
<p cross-fade>A system error occured while connecting with the server.</p>
<br>
<p cross-fade>Error message: {{dialogtext}}</p>
</section>
</core-animated-pages>
</content>
</paper-dialog>
</template>
<script type="application/dart" src="view.dart"></script>
</polymer-element>
/web/dialog/error/view.dart
import 'package:polymer/polymer.dart';
import '../view.dart'; // <- the base class 'DialogView'
#CustomTag('error-view')
class ErrorView extends DialogView{
ErrorView.created() : super.created(){
componentName = 'error-view';
this.dialogtitle = 'System Error';
}
}
/web/dialog/view.dart
import 'package:polymer/polymer.dart';
import 'dart:html';
import 'package:intl/intl.dart';
import '../locale/de.dart' as de;
class DialogView extends PolymerElement {
#observable int page;
//there are a lot of helper functions and variables in here
}
I use many pairs of those components extending the base component (which has no view.html but only a view.dart that allows me to hold and manipulate different dialogs within one List. This worked perfectly fine until I did the Pub Get / Upgrade and was not solved by repairing the cache. A project using a similar structure still works fine.
This resolves it for now:
pubspec.yaml
code_transformers: '<= 0.2.5'

<debug target crashed> error when selecting date in <input type='date'>

I have the following simple .dart and .html files
.dart
//import 'dart:html';
import 'package:polymer/polymer.dart';
/// A Polymer `<main-app>` element.
#CustomTag('main-app')
class MainApp extends PolymerElement {
#observable DateTime today = new DateTime.now();
#observable String aDate = '';
/// Constructor used to create instance of MainApp.
MainApp.created() : super.created();
void onChangeFired() {
print(aDate);
}
}
.html
<!-- import polymer-element's definition -->
<link rel="import" href="../../packages/polymer/polymer.html">
<link rel="import" href="../../packages/paper_elements/paper_input.html">
<polymer-element name="main-app">
<template>
<style>
:host {
display: block;
}
</style>
<input type='date' value='{{aDate}}'
on-change='{{onChangeFired}}' id='time' class='margin-lb5px'>
</template>
<script type="application/dart" src="main_app.dart"></script>
</polymer-element>
Running the app in Dartium displays the calendar dropdown. However, each time I select a date, the application crasshes (exits) after printing the selected date with the following
2005-02-08 (:1)
<debug target crashed>
Nothing else is displyed in the console.
I created a new new polymer-app using Stagehand with the same result. Nothing else is there in the application.
This problem is present in the last two Dart Dev updates - I am currently using Dart 1.9.0-dev.9.1 (rev 44018) with the same result.
I am using the Dart eclipse plugin on Windows 8.1
Thanks
This is an issue in the Chrome version Dartium is built on.
Hopefully with Dart 1.15 we get the updated Dartium where this issue should be fixed.

Object binding between Angular and Polymer in Dart

I'm trying to bind an object from an Angular controlled element to a Polymer element in Dart.
The object to bind:
class Person {
String name;
String surname;
Person(this.name, this.surname);
}
The polymer element template:
<link rel="import" href="packages/polymer/polymer.html">
<polymer-element name="person-element">
<template>
<style>
.label {font-weight: bold;}
</style>
<p>
<span class="label">Name: </span>{{person.name}}
<span class="label">Surname: </span>{{person.surname}}
</p>
</template>
<script type="application/dart" src="person_element.dart"></script>
</polymer-element>
The polymer element code:
import 'package:polymer/polymer.dart';
import 'person.dart';
#CustomTag('person-element')
class PersonElement extends PolymerElement {
#published Person person;
PersonElement.created() : super.created();
}
In Angular I've created a controller and a module:
#Controller(
selector: '[person-container]',
publishAs: 'ctrl')
class PersonController {
List<Person> persons = [new Person('John','Smith'), new Person('Mario','Rossi')];
}
class PersonModule extends Module {
PersonModule() {
bind(PersonController);
}
}
The first solution tried is using the angular_node_bind package:
<div person-container ng-cloak>
<h2>Person elements</h2>
<div ng-repeat="person in ctrl.persons">
<div>{{person.name}}</div>
<person-element person="[[person]]"></person-element>
</div>
</div>
When I run the application in Dartium I get this error:
Exception: type 'String' is not a subtype of type 'Person' of 'value'. (http://localhost:8080/person_element.dart:6)
I've also tried to modify the attribute instantiation in the html code in this way:
<person-element person=[[person]]></person-element>
But I get the same exception.
The angular_node_bind package supports the object binding?
The second solution is using the new binding features of Angular 0.14.0 and binding the polymer element in this way:
With this solution I don't get any exception, the element is visualized but the fields are empty and the person instance null.
The complete example is here: https://github.com/fedy2/dart-angular-polymer-object-data-binding
The new version of AngularDart (0.14.0) has a support for Polymer-Dart binding (http://blog.angulardart.org).
At the moment there can be some problems with different versions:
Pub get failed, [1] Resolving dependencies... Incompatible version constraints on code_transformers
You can find examples at
https://github.com/angular/angular.dart/pull/1461/files
https://github.com/angular/angular.dart/tree/master/example/web
https://github.com/angular/angular.dart/blob/master/example/web/paper.html
https://github.com/angular/angular.dart/blob/master/example/web/paper.dart
https://github.com/angular/angular.dart/blob/master/example/web/paper_radio_group.html
https://github.com/angular/angular.dart/blob/master/example/web/paper_radio_group.dart
also have a look at the same files in the sept15-prg branch.
the new syntax seems to be like
<person-element bind-person="person"></person-element>
It is possible that the released Angular version doesn't yet support some things used by this examples.

Polymer Elements in Dart Packages

I have a dart package that contains three extensions of polymer element: tp-element-a, tp-element-b and tp-element-c. For each of these elements there is a html-file containing the markup of the element and a dart file for the code. The tp-element-c contains references to the tp-element-a and tp-element-b.
The package structure looks like this:
testpolymer
pubspec.yaml
- packages
- asset
tp-element-a.html
tp-element-b.html
tp-element-c.html
- lib
testpolymer.dart
tp-element-a.dart
tp-element-b.dart
tp-element-c.dart
- web
index.html
The definitiopn of the polymer elements are very simple:
tp-element-a.html
<polymer-element name="tp-element-a">
<template>
<h1>Hello Element A</h1>
</template>
<script type="application/dart" src="../lib/tp-element-a.dart"></script>
</polymer-element>
tp-element-a.dart
part of testpolymer;
#CustomTag("tp-element-a")
class TpElementA extends PolymerElement {
TpElementA.created() : super.created() {}
}
I skip the definitions of tp-element-b and tp-element-c. They are similar. With the only difference that tp-element-c uses the tp-element-a and tp-element-b within its template markup.
The file testpolymer.dart contains the definition of the library testpolymer:
library testpolymer;
import "package:polymer/polymer.dart";
part "tp-element-a.dart";
part "tp-element-b.dart";
part "tp-element-c.dart";
In the yaml file I decalre the dependency to the polymer package and add the polymer transformer:
name: testpolymer
description: A pub package
dependencies:
polymer: any
transformers:
- polymer:
entry_points: web/index.html
Last not least the index.html just contains the link to the tp-element-c.html and uses this element:
<html>
<head>
<link rel="import" href="../asset/tp-element-c.html">
<script type="application/dart">export 'package:polymer/init.dart';</script>
<script src="packages/browser/dart.js"></script>
</head>
<body>
<div id="sample_container_id">
<tp-element-c></tp-element-c>
</div>
</body>
</html>
So far so good. But when I run a pub build I get errors, that are probably all caused by organizing the dart files in a library:
packages/testpolymer/tp-element-a.dart:1:1:
Directive not allowed here.
part of testpolymer;
packages/testpolymer/tp-element-a.dart:4:26:
A class can't extend a malformed type.
Try correcting the malformed type annotation or removing the 'extends' clause.
class TpElementA extends PolymerElement {
packages/testpolymer/tp-element-a.dart:3:2:
Cannot resolve 'CustomTag'.
#CustomTag("tp-element-a")
So how is it possible to include the code for polymer elements in libraries?
If I don't organize the polymer code as a library, I get another error in tp-element-c.dart, which imports (if no library is used) the tp-element-a.dart and the tp-element-b.dart directly:
The imported libraries 'tp-element-a.dart' and 'tp-element-b.dart' should not have the same name ''
How can I resolve this puzzle?
You get the last error message, if you don't have in each dart file unique library uniquename; definitions. In your case names could be: tp-element-a, tp-element-b etc.

Resources