I got a problem while deploying Dart code using Polymer to Javascript. I've created a polymer application with DartEditor and made a simple example. This example works in Dartium but when I try to build it as a Polymer App (in Javascript) and launch it, the app fails.
How am I supposed to convert a Dart Polymer app to Javascript ?
Here's the example code I made that fails :
example.html :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Example</title>
<link rel="import" href="example-polymer.html">
<script type="application/dart">export 'package:polymer/init.dart';</script>
<script src="packages/browser/dart.js"></script>
</head>
<body>
<div is="example-polymer"></div>
</body>
</html>
example-polymer.html
<polymer-element name="example-polymer" extends="div">
<template>
<div>
<input on-change="{{ change }}"/><br>
<span>Text : {{ text }}</span>
</div>
</template>
<script type="application/dart" src="example-polymer.dart"></script>
</polymer-element>
example-polymer.dart
import 'package:polymer/polymer.dart';
import 'dart:html';
#CustomTag('example-polymer')
class ExampleBolymer extends DivElement with Polymer, Observable {
#published String text = "" ;
ExampleBolymer.created() : super.created() {
}
void change(Event e, var detail , InputElement target) {
text = target.value;
}
}
add
transformers:
- polymer:
entry_points:
- web/example.html
to your pubspec.yaml
and call
pub build
Your files should be in the web directory of your package.
Related
Аfter compiling Dart code (which use Dart Polymer) to JS. I get the following error:
Uncaught Exception: The "smoke" library has not been configured.
Make sure you import and configure one of the implementations
(package:smoke/mirrors.dart or package:smoke/static.dart).
Sometimes the message was:
No elements registered in a while, but still waiting on 1 element to be registered. Check that you have a class with an #CustomTag annotation for each of the following tags: 'app-element'
What's wrong here? Here is my code:
UPDATE: now code beyond is improved and work correctly after pub build. I change folder/file structure and update polymer to the latest version.
pubspec.yaml
name: app
dependencies:
browser: any
#do not forget update to latest version by running pub update
polymer: any
transformers:
- polymer:
entry_points:
- web/main.html
web/templates/ui-elements.html
<polymer-element name="app-globals"></polymer-element>
<polymer-element name="app-element">
<template>
<link rel="stylesheet" href="/main.css"/>
<content></content>
</template>
<script type="application/dart" src="ui-elements.dart"></script>
</polymer-element>
web/templates/ui-elements.dart
#CustomTag('app-globals')
class AppGlobals extends PolymerElement{
AppGlobals.created() : super.created();
}
#CustomTag('app-element')
class AppElement extends PolymerElement {
AppElement.created() : super.created();
}
web/main.html (dummy entry file)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</head>
<body>
<app-element></app-element>
<script type="application/dart" src="main.dart"></script>
</body>
</html>
web/main.dart
import 'package:polymer/polymer.dart';
main() {
initPolymer();
}
#whenPolymerReady
void onReady() {
}
web/main.html (entry point) after pub build. Real mess after compiling. So many js files some of them takes size even more than 300kb.
<!DOCTYPE html><html lang="en"><head><script src="packages/web_components/webcomponents.min.js"></script><script src="packages/web_components/dart_support.js"></script>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</head>
<body><div hidden=""><style shim-shadowdom="">
/*******************************
Flex Layout
*******************************/
html /deep/ [layout][horizontal], html /deep/ [layout][vertical] {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
html /deep/ [layout][horizontal][inline], html /deep/ [layout][vertical][inline] {
display: -ms-inline-flexbox;
display: -webkit-inline-flex;
display: inline-flex;
}
......tons of other styles...........
</style>
<script src="packages/polymer/src/js/polymer/polymer.min.js"></script>
<script>
// TODO(sigmund): remove this script tag (dartbug.com/19650). This empty
// script tag is necessary to work around a bug in Chrome 36.
</script>
<!-- unminified for debugging:
<link rel="import" href="src/js/polymer/layout.html">
<script src="src/js/polymer/polymer.js"></script>
-->
<polymer-element name="app-globals"></polymer-element>
<!-- APP ELEMENT -->
<polymer-element name="app-element" class="bck-medusa w-100 h-100">
<template>
<link rel="stylesheet" href="../main.css">
<content></content>
</template>
</polymer-element>
</div>
<script src="main.html.polymer.bootstrap.dart.js" async=""></script>
</body></html>
You don't need initPolymer when you use #whenPolymerReady. The entire main() method is redundant in your example.
Did you register your entry page properly in the Polymer transformer configuration in pubspec.yaml?
Smoke needs a transformer but if you have the Polymer transformer configured properly the Smoke transformer is included.
I have a polymer element called main-app:
<link rel="import" href="../../packages/polymer/polymer.html">
<link rel="import" href="../../packages/paper_elements/paper_input.html">
<link rel="import" href="../../packages/paper_elements/paper_input.html">
<link rel="import" href="../../packages/paper_elements/paper_tabs.html">
<link rel="import" href="../../packages/paper_elements/paper_dialog.html">
<link rel="import" href="../../packages/paper_elements/paper_icon_button.html">
<link rel="import" href="../../packages/core_elements/core_toolbar.html">
<link rel="import" href="../../packages/core_elements/core_scaffold.html">
<link rel="import" href="../../packages/core_elements/core_header_panel.html">
<link rel="import" href="../../packages/core_elements/core_menu.html">
<link rel="import" href="../../packages/core_elements/core_item.html">
<link rel="import" href="../../packages/paper_elements/paper_input.html">
<link rel="import" href="../../packages/paper_elements/paper_button.html">
<link rel="import" href="../../packages/paper_elements/paper_dialog.html">
<link rel="import" href="../../packages/core_elements/core_scaffold.html">
<link rel="import" href="../../packages/core_elements/core_pages.html">
<polymer-element name="main-app" class="dark-primary-color">
<template>
<style type="text/css">
:host {
display: block;
}
</style>
<core-scaffold>
<core-header-panel id="menu-panel" navigation flex>
<core-toolbar id="navheader">
<span>Menu</span>
</core-toolbar>
<core-menu>
<core-item label="Home" on-click="{{homeClicked}}"></core-item>
<core-item label="About Us" on-click="{{aboutClicked}}"></core-item>
<core-item label="Contact Us" on-click="{{contactClicked}}"></core-item>
</core-menu>
</core-header-panel>
<span tool>{{title}}</span>
<paper-tabs class="main-menu bottom fit" selected="0">
<paper-tab on-click="{{homeClicked}}">Home</paper-tab>
<paper-tab on-click="{{aboutClicked}}">About Us</paper-tab>
<paper-tab on-click="{{contactClicked}}">Contact Us</paper-tab>
</paper-tabs>
<div class="content" forceNarrow>
<p>Lorem ipsum ...</p>
</div>
...
</core-scaffold>
</template>
<script type="application/dart" src="main-app.dart"></script>
</polymer-element>
main-app.dart:
import 'package:polymer/polymer.dart';
import 'util/util.dart';
import 'event/event.dart';
import 'dart:html';
import 'page/home-page.dart';
import 'page/about-page.dart';
import 'page/contact-page.dart';
#CustomTag('main-app')
class MainApp extends PolymerElement {
#observable String page = "home";
#observable String title = "Home";
MainApp.created() : super.created();
...
homeClicked(event, detail, target) {
CoreScaffold e = shadowRoot.querySelector('core-scaffold');
e.doSomething <<-- fails
...
}
...
}
This is the exception I'm getting:
Exception: 'package:falm/main-app.dart': malformed type: line 73 pos 5: type 'CoreScaffold' is not loaded
CoreScaffold e = shadowRoot.querySelector('core-scaffold');
^
type 'CoreScaffold' is not a subtype of type 'malformed' of 'e'.
To get rid of the exception, I now have to do:
homeClicked(event, detail, target) {
Element e = shadowRoot.querySelector('core-scaffold');
e.doSomething <<-- works
...
}
The code that is failing was working until a dart update yesterday morning (not sure from which version I updated as I reinstalled the SDK completely before doing a full pub upgrade, pub cache repair and pub download), PaperTabs is doing the same thing.
Does this mean I can no longer use CoreElement and PaperTabs classes in my dart code?
Update: here are the relevant bits and pieces from pubspec.lock:
core_elements:
description: core_elements
source: hosted
version: "0.6.0+4"
paper_elements:
description: paper_elements
source: hosted
version: "0.6.0+4"
polymer:
description: polymer
source: hosted
version: "0.15.5"
polymer_expressions:
description: polymer_expressions
source: hosted
version: "0.13.0+1"
web_components:
description: web_components
source: hosted
version: "0.10.1"
You need to import the libraries where the class is defined.
import 'package:core_elements/core_scaffold.dart';
import 'package:paper_elements/paper_tabs.dart';
checked/unchecked
When you run a Dart script from command line the default is production mode (unchecked mode). dart bin/somescript.dart, or checked mode when set explicitely like dart -c bin/somescript.dart.
When you launch a Dart script or web app from DartEditor default is checked mode. DartEditor allows to (de)activate Run in checked mode in Manage Launches (run configurations).
I assume there is a similar setting in Dart plugin for Eclipse (don't use it myself).
WebStorm allows to set it for command line apps in Run > Edit Configurations ... . For web apps you can create a new browser config and add --checked in the Command line options.
I assume it's similar in IntelliJ IDEA but I haven't used it myself yet.
See also https://stackoverflow.com/a/21658630/217408
I like to use my custom Polymer Element named content-page in my main-html.
Therefore I created a div with the id="contentcontainer" which contains my content-page.
For some reason it crashes, just after clicking on Run and the Dart Editor says: .
When I delete the line <link rel="import" href="content-page.html"> in main.html, the program isnt crashing, but there seems to be a Problem with the content of my main().
I unfortunately have no specific question, because I dont know where the error might be or where to start. Does someone see some suspicious parts in my code?
Thanks for helping!
main.dart:
import 'dart:html';
void main() {
var newElement = new Element.tag('content-page');
querySelector('#contentcontainer').children.add(newElement);
}
main.html:
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="style.css">
<script type="application/dart" src="main.dart"></script>
<script src="packages/web_components/dart_support.js"></script>
<link rel="import" href="content-page.html">
</head>
<body>
<div id="contentcontainer">
<content-page id="contentpage"></content-page>
</div>
<script type="application/dart">export 'package:polymer/init.dart';</script>
</body>
</html>
content-page.dart:
import 'package:polymer/polymer.dart';
import 'dart:html';
#CustomTag('content-page')
class ContentPage extends PolymerElement {
ContentPage.created() : super.created();
}
content-page.html:
<link rel="import" href="../packages/polymer/polymer.html">
<polymer-element name="content-page" >
<template>
<div>
ContentPage-Content
</div>
</template>
<script type="application/dart" src="content-page.dart"></script>
</polymer-element>
I tried your code and it's ok. Have you added the transformers to your pubspec.yaml?
name: sample
description: A sample web application
dependencies:
browser: any
polymer: any
transformers:
- polymer
You should have a look at this question/answer: how to implement a main function in polymer apps how to use a custom main method in a Polymer project.
This line should contain your file containing your main method (see also the answer in the linked question):
<script type="application/dart">export 'package:polymer/init.dart';</script>
this line is then redundant
<script type="application/dart" src="main.dart"></script>
the transformer configuration also needs a list of entry pages if you don't use the latest Polymer version
transformers:
- polymer:
entry_points:
- web/index.html
The Dart editor currently supports only one dart polymer (/file) new project generation option. And this option sets up 4 files in the /web subdir without a main(), and arriving at a main requires some boiler-plate changes that were not totally obvious to me.
I was helped on the Dart Forum for this somewhat "howto" question by Guenter Zoeckbauer, so I want to share the results of those minimal changes to this nice minimal project, that has provided me with exactly the starting point need to re-base my outdated code and file structure on.
It seems to me it provides good starting point reference for re-building apps that have gotten out of date with all the rapid and IMPORTANT changes that have been made in the last few months.
Here are the 6 files as they must be modified (the app name is: app_with_main):
1 app_with_main.css NO CHANGE
2 clickcounter.dart NO CHANGE
3 clickcounter.html NO CHANGE
4 index.html:
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sample app</title>
<!-- <script src="packages/web_components/platform.js"></script>
not necessary anymore with Polymer >= 0.14.0 -->
<script src="packages/web_components/dart_support.js"></script>
<link rel="import" href="clickcounter.html">
<!-- ORIGINAL SCRIPT
<script type="application/dart">export 'package:polymer/init.dart';</script>
<script src="packages/browser/dart.js"></script>
-->
<link rel="stylesheet" href="app_with_main.css">
</head>
<body>
<h1>App with main</h1>
<p>Hello world from Dart!</p>
<div id="sample_container_id">
<click-counter count="5"></click-counter>
</div>
<script type="application/dart">export 'init.dart';</script>
</body>
</html>
#5 . init.dart (new)
import "package:polymer/polymer.dart";
main() {
print("always before polymer initialization is complete");
initPolymer().run(() {
print('''Code here will be called almost immediately and cannot rely
on the polymer elements being instantiated.''');
Polymer.onReady.then((_) {
print('''at this point the onReady callback has been returned and thus the polymer
initialization process will be complete''');
});
});
6 The project yaml file must be modified to set the entry_point to index.html thus:
name: app_with_main
description: A sample Polymer application
dependencies:
polymer: ">=0.11.0-dev.2 <0.12.0"
transformers:
- polymer:
entry_points: web/index.html
And that should do it, you should be off and running with a code structure that can grow with your project for a long time....
Thanks again to Dart Super Hero Guenter Zoecchbauer!
For reference and comparison I think it is useful to also consider the skeleton Polymer Dart app that gets generated by the Chrome Dev Editor. It includes a Dart main().
Below I've posted index.html, and main.dart from the web folder of a freshly generated Polymer Dart Paper elements project (as of 2014-10-10).
Note that these reference a sample_app custom element which gets generated into the lib folder, but pasting that below as well would be too long.
1. Index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HelloDartWebPaper</title>
<link rel="stylesheet" href="styles.css">
<script src="packages/web_components/platform.js"></script>
<script src="packages/web_components/dart_support.js"></script>
<link rel="import" href="packages/HelloDartWebPaper/sample_app.html">
</head>
<body unresolved>
<sample-app></sample-app>
<script src="main.dart" type="application/dart"></script>
<script src="packages/browser/dart.js"></script>
</body>
</html>
2. main.dart
import 'package:polymer/polymer.dart';
import 'package:paper_elements/paper_toast.dart';
import 'package:HelloDartWebPaper/sample_app.dart';
void main() {
// Init polymer.
initPolymer();
// Register Polymer components (ones that are actually used in the app).
registerWidgetsWithPolymer();
}
#initMethod
void postPolymerBoot() {
print('Polymer init complete.');
}
void registerWidgetsWithPolymer() {
upgradePaperToast();
Polymer.register('sample-app', SampleApp);
}
styles.css
omitted - not relevant
sample_app component in lib.
I was fiddling with the "new" instructions for polymer dart 0.10.0-pre.10 only to realize I had package 0.9.5 installed (on an updated Dart Editor). And could only get code to run using main() => dostuff(); Adding component1 as per instructions just broke whatever worked.
I set pubspec.yaml polymer dependency to >= 0.9.9 and it auto pub gets the version 0.10.0-pre.10. Then I made changes as suggested and moved dostuff() to a custom element class (extends PolymerElement) and put #initMethod above it. It does not run.
And as I got it to run before I was unable to find a way to bind new items from a JSON file (which I successfuly got through http) to the polymer element.
mylist.dart
import 'package:polymer/polymer.dart';
import 'dart:html';
#CustomTag('my-list')
class MyListElement extends PolymerElement {
#observable List mylist = ['one', 'two', 'three'];
#initMethod
static dostuff() {
print("initMethod");
// get json and pass to mylist
}
}
mylist.html
<polymer-element name="my-list">
<template>
<ul>
<template repeat="{{item in mylist}}">
<li>{{item}}</li>
</template>
</ul>
</template>
<script type="application/dart;component=1" src="mylist.dart"></script>
</polymer-element>
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sample app</title>
<link rel="import" href="packages/polymer/polymer.html">
<link rel="import" href="mylist.html">
<script src="packages/browser/dart.js"></script>
</head>
<body>
<h1>MyList</h1>
<div id="container1">
<json-list id="my-list1"></json-list>
</div>
</body>
</html>
This code (especially #initMethod) inside the element doesn't make sense.
#CustomTag('my-list') does this already. You need #initMethod() only when you want a method executed like main() that is outside of an Polymer element.
You can put this code inside the constructor of MyListElement or better inside polymerCreated before the super call.
import 'package:polymer/polymer.dart';
import 'dart:html';
#CustomTag('my-list')
class MyListElement extends PolymerElement {
#observable List mylist = ['one', 'two', 'three'];
#override
polymerCreated() {
print("initMethod");
// get json and pass to mylist
super.polymerCreated();
}
}
You didn't get Polymer 0.10.0-pre.10 because it is a pre-release which is indicated by the - after the patch version (not by pre).
Pub by default ignores pre-releases. You have to enforce them by a version constraint like '>=0.10.0-'