<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CkMCRHc6eip7ImA9WhBbEkg.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634</id><updated>2013-05-10T22:34:25.912-07:00</updated><category term="flash" /><category term="icons" /><category term="pojo" /><category term="hosting" /><category term="scaling" /><category term="algorithms" /><category term="rubyonrails" /><category term="owl" /><category term="audio" /><category term="activewarehouse" /><category term="sudoku" /><category term="sqlserver" /><category term="git" /><category term="javapolis" /><category term="rails" /><category term="video" /><category term="email" /><category term="combinations" /><category term="xhtml" /><category term="mashup" /><category term="work" /><category term="googleio" /><category term="scripting" /><category term="thespringexperience" /><category term="facebook" /><category term="fixtures" /><category term="i18n" /><category term="aop" /><category term="information" /><category term="swoop" /><category term="aspectj" /><category term="tune" /><category term="networking" /><category term="crud" /><category term="rest" /><category term="io2011" /><category term="mvc" /><category term="controller" /><category term="interview" /><category term="qotd" /><category term="springwebflow" /><category term="Web Architecture" /><category term="dns" /><category term="groovy" /><category term="flickr" /><category term="view" /><category term="delicious" /><category term="rocketboom" /><category term="mac" /><category term="railsconf" /><category term="mp3" /><category term="framework" /><category term="j2ee" /><category term="owl1.1" /><category term="json" /><category term="subversion" /><category term="google" /><category term="pig" /><category term="Python" /><category term="activerecord" /><category term="alohaonrails" /><category term="messaging" /><category term="opendns" /><category term="song" /><category term="documentary" /><category term="osx" /><category term="consensus" /><category term="dhtml" /><category term="protege" /><category term="bigtable" /><category term="sparql" /><category term="tdd" /><category term="dataweb" /><category term="Crypto" /><category term="Social Networking" /><category term="Agile Programming" /><category term="springframework" /><category term="foaf" /><category term="math" /><category term="charts" /><category term="startup" /><category term="deployment" /><category term="arpanet" /><category term="music" /><category term="xslt" /><category term="cube" /><category term="bookmarks" /><category term="tivo" /><category term="netbeans" /><category term="inference" /><category term="railsconf07" /><category term="switchtower" /><category term="javascript extjs" /><category term="Ruby" /><category term="drools" /><category term="hioug" /><category term="health" /><category term="gmail" /><category term="html5 ruby rails" /><category term="openid" /><category term="magazine" /><category term="html5" /><category term="erlang" /><category term="web" /><category term="coucdb" /><category term="annotations" /><category term="deliciouslinks" /><category term="storage" /><category term="puzzle" /><category term="box2d" /><category term="ontology" /><category term="mapreduce" /><category term="hadoop" /><category term="presentation" /><category term="HTTP" /><category term="#dart" /><category term="reasoner" /><category term="applications" /><category term="css" /><category term="folksonomy" /><category term="spring" /><category term="coordination" /><category term="migrations" /><category term="performance" /><category term="jess" /><category term="eclipse" /><category term="errorlytics" /><category term="webdev" /><category term="chrome web store" /><category term="http://dmoz.org/Computers/Internet/On_the_Web/Weblogs/" /><category term="xp" /><category term="blogs" /><category term="grddl" /><category term="humor" /><category term="vanity" /><category term="contest" /><category term="acegi" /><category term="buttons" /><category term="business" /><category term="scala" /><category term="mysql" /><category term="soundboard" /><category term="semantic web" /><category term="esb" /><category term="XML" /><category term="algorithm" /><category term="cloud" /><category term="olap" /><category term="oracle" /><category term="microformats" /><category term="movie" /><category term="rspec" /><category term="dartlang" /><category term="expertspringmvc" /><category term="filesystem" /><category term="software" /><category term="#io2011" /><category term="html" /><category term="distributedsystems" /><category term="trendline" /><category term="newgame" /><category term="hjug" /><category term="jms" /><category term="xmlschema" /><category term="thespringframework" /><category term="w3c" /><category term="uri" /><category term="web design" /><category term="uh" /><category term="couchdb" /><category term="rules" /><category term="webcomponents" /><category term="trust" /><category term="javascript" /><category term="fuse" /><category term="mule" /><category term="jena" /><category term="im" /><category term="postfix" /><category term="graphs" /><category term="conference" /><category term="graph" /><category term="Ontologies" /><category term="Programming" /><category term="browsers" /><category term="dart" /><category term="rdf" /><category term="transactions" /><category term="General" /><category term="browser" /><category term="forms" /><category term="aspects" /><category term="windows" /><category term="science" /><category term="database" /><category term="linux" /><category term="hibernate" /><category term="unittests" /><category term="php" /><category term="supermariobrothers" /><category term="ajax" /><category term="patterns" /><category term="tutorial" /><category term="timbl" /><category term="games" /><category term="oop" /><category term="petstore" /><category term="Java" /><category term="book" /><category term="blog" /><category term="springmvc" /><category term="nas" /><category term="regressionline" /><category term="Blogging" /><category term="pagination" /><category term="activeresource" /><category term="hawaii" /><category term="tags" /><category term="tests" /><category term="#dartlang" /><category term="appengine" /><category term="radrails" /><category term="web2.0" /><category term="food" /><category term="search" /><category term="softwareengineering" /><category term="tagging" /><category term="model" /><category term="HTML amp; CSS" /><category term="spring.net" /><category term="capistrano" /><category term="data" /><category term="metadata" /><category term="pellet" /><title>Seth Ladd's Blog</title><subtitle type="html">Dart DevRel @ Google, web engineer, author, conference organizer.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.sethladd.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.sethladd.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>893</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/sethladd/aGPE" /><feedburner:info uri="sethladd/agpe" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CUYFQ3syeSp7ImA9WhBVF0U.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-5986305417236804047</id><published>2013-04-23T22:47:00.001-07:00</published><updated>2013-04-23T22:58:32.591-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-23T22:58:32.591-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>Lazy Load Libraries in Dart</title><content type="html">Dart is a statically analyzable language, and its tree-shaking compiler does a good job of eliminating dead code and producing a single, optimized application file. However, sometimes developers need to control when certain libraries are loaded and thus need to control which libraries are included in the main application file. To help, the dart2js compiler, which converts Dart code into JavaScript code, now supports lazy-loaded libraries.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-mt92rQOSk_Q/UXdx0aKXAfI/AAAAAAAAV1Y/zCqHR0Le-hc/s1600/87885327_b0db9347cf.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-mt92rQOSk_Q/UXdx0aKXAfI/AAAAAAAAV1Y/zCqHR0Le-hc/s1600/87885327_b0db9347cf.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Lazy Load&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
As an example, consider an application that has many different screens. Some screens are more obscure than others, and aren't required for the application to start. A developer should be able to say "I don't need these screens now, but pull them in when I do need them." This lazy-loading is a common deployment strategy for web apps, because small initial loads means faster application startup.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
You can mark a library as "lazy", and the dart2js compiler will output a separate JavaScript file for that library. Note that dart2js still performs tree shaking (aka dead code elimination) across the entire app (technically, across the entire isolate). This means that only the functionality required from the lazy-loaded library will actually be compiled into the separate file.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The lazy-loaded library is still part of the application structure, and must exist and be available to dart2js when the program is compiled. This is not "dynamic loading", per se, because the application must statically import all libraries (lazy or not).&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
(Note: as of the time of this writing, dart2js emits at most one other JavaScript file. This restriction will be removed and you will be able to emit multiple files for a single application. Please track &lt;a href="https://code.google.com/p/dart/issues/detail?id=3940"&gt;Dartbug 3940&lt;/a&gt; to learn more.)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;DeferredLibrary Example&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The main application can mark a library with an&amp;nbsp;@lazy metadata. Then, it declares an instance of &lt;a href="http://api.dartlang.org/docs/bleeding_edge/dart_async/DeferredLibrary.html"&gt;DeferredLibrary&lt;/a&gt; that points to the outputted JavaScript file.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div class="p1"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span class="s1"&gt;import &lt;/span&gt;'dart:html'&lt;span class="s1"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span class="s1"&gt;import &lt;/span&gt;'dart:async'&lt;span class="s1"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;@lazy&lt;/span&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span class="s1"&gt;import &lt;/span&gt;'reverser.dart'&lt;span class="s1"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span class="s2"&gt;const&lt;/span&gt; lazy = &lt;span class="s2"&gt;const&lt;/span&gt; DeferredLibrary(&lt;span class="s3"&gt;'reverser'&lt;/span&gt;, uri: &lt;span class="s3"&gt;'./part.js'&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span class="s2"&gt;void&lt;/span&gt; main() {&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; lazy.load().then((_) {&lt;/span&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span class="s1"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;print(&lt;/span&gt;'library loaded'&lt;span class="s1"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span class="s1"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;query(&lt;/span&gt;"#sample_text_id"&lt;span class="s1"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;..text = &lt;span class="s3"&gt;"Click me!"&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;..onClick.listen(reverseText);&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;});&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span class="s2"&gt;void&lt;/span&gt; reverseText(MouseEvent event) {&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; query(&lt;span class="s3"&gt;"#sample_text_id"&lt;/span&gt;).text =&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; reverse(query(&lt;span class="s3"&gt;"#sample_text_id"&lt;/span&gt;).text);&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
Notice how the library doesn't come into existence until after the Future from &lt;span style="font-family: Courier New, Courier, monospace;"&gt;lazy.load()&lt;/span&gt; completes. Only then can you call into the library.&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
The runtime throws NoSuchMethodError if you try to access functionality from a library that it not yet loaded.&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-size: large;"&gt;More to come&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
The lazy-load functionality of dart2js is just the beginning. In the future, you will be able to mark multiple libraries as "lazy", and really control how you deploy and load your web application.&lt;br /&gt;
&lt;br /&gt;
Also, this functionality only currently works with dart2js. Please star &lt;a href="https://code.google.com/p/dart/issues/detail?id=10171"&gt;Dartbug 10171&lt;/a&gt; if you are interested in seeing the same lazy-loading for the VM and Dartium.&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
Please try this out, we look forward to your feedback!&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
(Photo Credit: &lt;a href="http://www.flickr.com/photos/87603889@N00/87885327/"&gt;Marcus Hansson&lt;/a&gt;&amp;nbsp;licensed under&amp;nbsp;&lt;a href="http://creativecommons.org/licenses/by/2.0/"&gt;cc&lt;/a&gt;)&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/EhU7euhpr50" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/5986305417236804047/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=5986305417236804047&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/5986305417236804047?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/5986305417236804047?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/EhU7euhpr50/lazy-load-libraries-in-dart.html" title="Lazy Load Libraries in Dart" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-mt92rQOSk_Q/UXdx0aKXAfI/AAAAAAAAV1Y/zCqHR0Le-hc/s72-c/87885327_b0db9347cf.jpg" height="72" width="72" /><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2013/04/lazy-load-libraries-in-dart.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEERn88eyp7ImA9WhBVF0o.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-1421143591573065874</id><published>2013-04-23T21:17:00.000-07:00</published><updated>2013-04-23T21:26:47.173-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-23T21:26:47.173-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>Dynamically Load Code with Dart</title><content type="html">Rejoice! Dartium, a build of Chromium with the Dart VM, can now spawn a new isolate from a URI. This means your Dart apps have a new option for more modular code.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Isolates&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
In Dart, an &lt;i&gt;isolate&lt;/i&gt; is an abstraction for an "isolated memory heap". Isolates do not share memory (variables, statics, etc), they are essentially self-contained applications. Isolates communicate by sending and receiving messages over &lt;i&gt;ports&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-lKoB2jUTX6U/UXdS8wuphdI/AAAAAAAAV1I/Jf78_URD_Fc/s1600/Dart+isolates+diagram+(1).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-lKoB2jUTX6U/UXdS8wuphdI/AAAAAAAAV1I/Jf78_URD_Fc/s1600/Dart+isolates+diagram+(1).png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Why Isolates Matter&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Dart programs are static, in that their shape and structure do not change after they are compiled. A static program is great for optimizations like tree shaking (aka dead code elimination), type-inferencing compilers, and more.&lt;br /&gt;
&lt;br /&gt;
However, modular apps often require a way to dynamically load code. Configurable and modular apps need a way to, at run time, pull in new functionality. If Dart apps have a static structure, how can they dynamically alter their behavior?&lt;br /&gt;
&lt;br /&gt;
Isolates to the rescue! The structure inside of an isolate is static, but a Dart program is free to dynamically load other isolates. This means that libraries can be loaded into isolates at run time.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Your First Isolate&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This simple&amp;nbsp;&lt;i&gt;reverser&lt;/i&gt;&amp;nbsp;isolate listens on its port, receives messages, reverses them, and send the reversed text back to the sender.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;// reverser.dart&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div class="p1"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span class="s1"&gt;import&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;'dart:isolate'&lt;span class="s2"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span class="s3"&gt;main&lt;/span&gt;() {&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &lt;span class="s4"&gt;port&lt;/span&gt;.receive((msg, SendPort replyTo) {&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &lt;span class="s1"&gt;var&lt;/span&gt; reverse = msg &lt;span class="s1"&gt;as&lt;/span&gt; String;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &lt;span class="s1"&gt;var&lt;/span&gt; buffer = &lt;span class="s1"&gt;new&lt;/span&gt; StringBuffer();&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &lt;span class="s1"&gt;for&lt;/span&gt; (&lt;span class="s1"&gt;var&lt;/span&gt; i = reverse.&lt;span class="s4"&gt;length&lt;/span&gt; - &lt;span class="s5"&gt;1&lt;/span&gt;; i &amp;gt;= &lt;span class="s5"&gt;0&lt;/span&gt;; i--) {&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; buffer.write(reverse[i]);&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; replyTo.send(buffer.toString());&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; });&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
The main application (which itself is an isolate), is responsible for instantiating the reverser isolate. Use the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;spawnUri()&lt;/span&gt; function from &lt;span style="font-family: Courier New, Courier, monospace;"&gt;dart:isolate&lt;/span&gt; to spawn a new isolate from some file.&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;// main.dart&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;SendPort &lt;span class="s1"&gt;reverser&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span class="s2"&gt;void&lt;/span&gt; &lt;span class="s3"&gt;main&lt;/span&gt;() {&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span class="s4"&gt;&amp;nbsp; query(&lt;/span&gt;"#sample_text_id"&lt;span class="s4"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span class="s4"&gt;&amp;nbsp; &amp;nbsp; ..&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="s4"&gt; = &lt;/span&gt;"Click me!"&lt;/span&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; ..&lt;span class="s1"&gt;onClick&lt;/span&gt;.listen(reverseText);&lt;/span&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &lt;span class="s2"&gt;var&lt;/span&gt; serviceFile = &lt;span class="s5"&gt;'reverser.dart'&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p4"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span class="s4"&gt;&amp;nbsp; &lt;/span&gt;&lt;span class="s2"&gt;if&lt;/span&gt;&lt;span class="s4"&gt; (identical(&lt;/span&gt;&lt;span class="s6"&gt;1&lt;/span&gt;&lt;span class="s4"&gt;, &lt;/span&gt;&lt;span class="s6"&gt;1.0&lt;/span&gt;&lt;span class="s4"&gt;)) {&amp;nbsp; &lt;/span&gt;// &lt;span class="s7"&gt;XXX&lt;/span&gt;: horrible hack to detect if we're in JS&lt;/span&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; serviceFile = &lt;span class="s5"&gt;'reverser.dart.js'&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &lt;span class="s1"&gt;reverser&lt;/span&gt; = spawnUri(serviceFile);&lt;/span&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
Notice the horrible hack to detect if this code is running in the Dart VM or JavaScript. I don't know a better way to do it, but I don't recommend this.&lt;/div&gt;
&lt;div class="p2"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
When the text from #sample_text_id is clicked, the reverseText function is run:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="p1"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;span class="s1"&gt;void&lt;/span&gt; &lt;span class="s2"&gt;reverseText&lt;/span&gt;(MouseEvent event) {&lt;/span&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &lt;span class="s1"&gt;var&lt;/span&gt; text = query(&lt;span class="s3"&gt;"#sample_text_id"&lt;/span&gt;).&lt;span class="s4"&gt;text&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &lt;span class="s4"&gt;reverser&lt;/span&gt;.call(text).then((reversed) {&lt;/span&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; query(&lt;span class="s3"&gt;"#sample_text_id"&lt;/span&gt;).&lt;span class="s4"&gt;text&lt;/span&gt; = reversed;&lt;/span&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; });&lt;/span&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
Notice how the reverser isolate is sent a message via call(), which returns a Future. When the Future completes, the callback registered with then() is run.&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;span style="font-size: large;"&gt;Support&lt;/span&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
Dartium supports spawnUri since at least version 28.0.1478.0 (194114). Dart2js compiles spawnUri() into a Web worker.&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
Note that each isolate is its own app, so dart2js must compile the same bootstrap code into each isolate file.&lt;/div&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/crw8ORXbGME" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/1421143591573065874/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=1421143591573065874&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/1421143591573065874?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/1421143591573065874?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/crw8ORXbGME/dynamically-load-code-with-dart.html" title="Dynamically Load Code with Dart" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-lKoB2jUTX6U/UXdS8wuphdI/AAAAAAAAV1I/Jf78_URD_Fc/s72-c/Dart+isolates+diagram+(1).png" height="72" width="72" /><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2013/04/dynamically-load-code-with-dart.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AMR38zcSp7ImA9WhBVE0w.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-4428229519982379724</id><published>2013-04-18T13:09:00.001-07:00</published><updated>2013-04-18T13:09:46.189-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-18T13:09:46.189-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>6 Dart FAQs - Answered!</title><content type="html">&lt;a href="https://plus.google.com/105922896126183852742"&gt;Calvin Prewitt&lt;/a&gt; wrote some good &lt;a href="https://plus.google.com/u/0/+SethLadd/posts/25HSRX13wUh"&gt;questions about Dart&lt;/a&gt; via G+. It might be hard to find his questions and my answers, so I hoisted them here. Enjoy!&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Q) Could you also detail compatibility and which JavaScript APIs are fully or partially supported for Dart2JS production code?&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;A) All JavaScript APIs supported by Chrome should be available to Dart. See &lt;a href="http://www.dartlang.org/articles/improving-the-dom/"&gt;http://www.dartlang.org/articles/improving-the-dom/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Q) It appears Dart is aiming to eventually replace it? The FAQ says it only targets modern browser versions.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;A) Dart's aim is to give developers like you a very productive experience, and give your users a very fast experience. Dart targets IE9+, plus the modern versions of Firefox, Chrome, Safari, mobile safari, and Chrome for Android. Basically, modern browsers.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Q) Is there a way to have fine grained control over the JS code like in Closure?&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;A) Dart2js can emit a single file, plus up to one other lazily loaded library. In the future, we want to give you more control. Here's the bug: &lt;a href="https://code.google.com/p/dart/issues/detail?id=10023"&gt;https://code.google.com/p/dart/issues/detail?id=10023&lt;/a&gt; Please note, dart2js's output is already smaller thanks to tree-shaking.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Q) I've noticed a lot of similarities to Closure Library. Has some or all of the Closure Library code been ported?&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;A) I'm unaware of an "official" port from the closure libraries. In general, though, you shouldn't need it. Dart's core libraries are pretty comprehensive. Check out &lt;a href="http://api.dartlang.org/"&gt;http://api.dartlang.org&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Q) Is Dart ready for production use? Specifically for generating JS code. If not, what's missing or where are the sore spots?&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;A) Dart's M4 release just came out, promising no more breaking changes to the core libs. Hurray! There's still work to do, but the platform just got much more stable. If you see something missing, let us know: &lt;a href="http://dartbug.com/new"&gt;http://dartbug.com/new&lt;/a&gt;&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Q) Finally, where can I help? Closure is nowhere near a productive environment. If Dart is aiming to make building complex web apps easier than working with Closure, I'd like to contribute to that goal.﻿&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;A) Yes, we're "aiming to hit a productivity and performance bullseye" (groan :) We'd love help. Dart is open source, so check out &lt;a href="http://dartbug.com/"&gt;http://dartbug.com/&lt;/a&gt; and out Github presence at&lt;a href="http://github.com/dart-lang"&gt;http://github.com/dart-lang&lt;/a&gt; Join our Dartisans community in G+, too&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/RS18MB1Az9M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/4428229519982379724/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=4428229519982379724&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/4428229519982379724?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/4428229519982379724?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/RS18MB1Az9M/6-dart-faqs-answered.html" title="6 Dart FAQs - Answered!" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2013/04/6-dart-faqs-answered.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cGSXs8cSp7ImA9WhBXEko.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-6717680143352629540</id><published>2013-03-25T21:34:00.001-07:00</published><updated>2013-03-25T22:17:08.579-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-25T22:17:08.579-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>First Look at Dart Mixins</title><content type="html">You can use &lt;i&gt;mixins&lt;/i&gt; to help inject behavior into your classes without using inheritance. Use a mixin when you have shared functionality that doesn't fit well in a &lt;i&gt;is-a&lt;/i&gt;&amp;nbsp;relationship.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img border="0" src="http://1.bp.blogspot.com/-k_PxdBf6fR4/UVEkgVmt_II/AAAAAAAAVbE/wEurF9mx0xc/s1600/5406671277_5d6d9329bb.jpg" /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Dart supports a basic form of &lt;a href="http://www.dartlang.org/articles/mixins/"&gt;mixins&lt;/a&gt; as of the M3 release in early 2013. The language designers expect to expand on mixins' abilities in future versions of the language.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Surprisingly, you've been using the concept of a mixin all along. Dart considers a mixin as the &lt;i&gt;delta between a subclass and its superclass&lt;/i&gt;. That is, every time you define an &lt;i&gt;is-a&lt;/i&gt;&amp;nbsp;relationship with the &lt;i&gt;extends&lt;/i&gt;&amp;nbsp;keyword, you are really defining a delta between the new class and its parent class. In other words, a subclass definition is like a mixin definition.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Given that short description, it should come as no surprise that an abstract class (with a few restrictions) is itself a mixin. Here is an example of a Persistance mixin:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre style="background-color: #f0f0f0; border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; width: 450.828125px;"&gt;&lt;code style="word-wrap: normal;"&gt; abstract class Persistence {  
  void save(String filename) {  
   print('saving the object as ${toJson()}');  
  }  
    
  void load(String filename) {  
   print('loading from $filename');  
  }  
    
  Object toJson();  
 }  &lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Restrictions on mixin definitions include:&lt;/div&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;Must not declare a constructor&lt;/li&gt;
&lt;li&gt;Superclass is Object&lt;/li&gt;
&lt;li&gt;Contains no calls to super&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
You can use the mixin with the &lt;i&gt;with&lt;/i&gt;&amp;nbsp;keyword. Here is an example:&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre style="background-color: #f0f0f0; border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; width: 450.828125px;"&gt;&lt;code style="word-wrap: normal;"&gt; abstract class Warrior extends Object &lt;b&gt;with Persistence&lt;/b&gt; {  
  fight(Warrior other) {  
   // ...  
  }  
 }  
   
 class Ninja extends Warrior {  
  Map toJson() {  
   return {'throwing_stars': true};  
  }  
 }  
   
 class Zombie extends Warrior {  
  Map toJson() {  
   return {'eats_brains': true};  
  }  
 } &lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
In the above example, both Ninja and Zombie extend from Warrior. This makes sense, they are both warriors, so the &lt;i&gt;is-a&lt;/i&gt;&amp;nbsp;relationship applies. All warriors can be persisted and loaded from a database, but this is purely behavior and the statement &lt;i&gt;Warrior is-a Persistence&lt;/i&gt;&amp;nbsp;simply doesn't make sense. Inheritance does not apply here, but we can use a mixin to inject the functionality.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre style="background-color: #f0f0f0; border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; width: 450.828125px;"&gt;&lt;code style="word-wrap: normal;"&gt; main() {  
  var ninja = new Ninja();  
  ninja.save('warriors.txt');  
    
  var zombie = new Zombie();  
  zombie.save('warriors.txt');  
 }  &lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
A class that uses a mixin is also a member of the mixin's type:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #f0f0f0; border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; width: 450.828125px;"&gt;&lt;code style="word-wrap: normal;"&gt; print(ninja is Persistence); // true!  &lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Mixins are fairly new to Dart, so they aren't widely deployed. We're curious to see how you use mixins. Let us know on the &lt;a href="mailto:misc@dartlang.org"&gt;Dart mailing list&lt;/a&gt;, and please &lt;a href="http://dartbug.com/"&gt;file any bugs&lt;/a&gt; you may encounter. Thanks!&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: x-small;"&gt;(Photo courtesy of&amp;nbsp;&lt;a href="http://www.flickr.com/photos/58871905@N03/5406671277/"&gt;http://www.flickr.com/photos/58871905@N03/5406671277/&lt;/a&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/L_PXcECc_WY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/6717680143352629540/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=6717680143352629540&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/6717680143352629540?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/6717680143352629540?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/L_PXcECc_WY/first-look-at-dart-mixins.html" title="First Look at Dart Mixins" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-k_PxdBf6fR4/UVEkgVmt_II/AAAAAAAAVbE/wEurF9mx0xc/s72-c/5406671277_5d6d9329bb.jpg" height="72" width="72" /><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2013/03/first-look-at-dart-mixins.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkAHSHk9eyp7ImA9WhBQGE8.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-5855116199247716656</id><published>2013-03-20T17:10:00.001-07:00</published><updated>2013-03-20T17:12:19.763-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-20T17:12:19.763-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>Dart on FLOSS Weekly from TWiT Network</title><content type="html">Today I had the pleasure of chatting about &lt;a href="http://www.dartlang.org/" target="_blank"&gt;Dart&lt;/a&gt; with Randal Schwartz and Aaron Newcomb on &lt;a href="http://twit.tv/show/floss-weekly" target="_blank"&gt;FLOSS Weekly&lt;/a&gt;&amp;nbsp;(part of the &lt;a href="http://twit.tv/" target="_blank"&gt;TWiT network&lt;/a&gt;). We talked about the&amp;nbsp;Dart language, its developer ecosystem, and the future of the project.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://twit.tv/show/floss-weekly/245" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="223" src="http://4.bp.blogspot.com/-YuqltAZe5qk/UUpQTGYwTSI/AAAAAAAAVXI/2g3QIYdChsQ/s400/Screen+Shot+2013-03-20+at+5.11.34+PM.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
You can &lt;a href="http://twit.tv/show/floss-weekly/245" target="_blank"&gt;watch the entire video&lt;/a&gt; of the interview, embedded below for easy viewing:&lt;br /&gt;
&lt;br /&gt;
&lt;iframe align="middle" frameborder="0" height="320" hspace="0" marginheight="0" marginwidth="0" scrolling="no" src="http://twit.tv/embed/12691" width="640"&gt;&lt;/iframe&gt;

&lt;br /&gt;
Thanks to Randal and Aaron for a lively discussion. They are awesome hosts and I highly recommend you tune in.&lt;br /&gt;
&lt;br /&gt;
Have Dart questions? Join us on the &lt;a href="http://www.dartlang.org/mailing-list" target="_blank"&gt;mailing list&lt;/a&gt; or the &lt;a href="https://plus.google.com/communities/114566943291919232850" target="_blank"&gt;Dartisans G+ Community&lt;/a&gt;. We love feedback!&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/7yeiecynzeE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/5855116199247716656/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=5855116199247716656&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/5855116199247716656?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/5855116199247716656?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/7yeiecynzeE/dart-on-floss-weekly-from-twit-network.html" title="Dart on FLOSS Weekly from TWiT Network" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-YuqltAZe5qk/UUpQTGYwTSI/AAAAAAAAVXI/2g3QIYdChsQ/s72-c/Screen+Shot+2013-03-20+at+5.11.34+PM.png" height="72" width="72" /><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2013/03/dart-on-floss-weekly-from-twit-network.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUEQnkyeyp7ImA9WhBQF0w.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-774837463202951120</id><published>2013-03-19T09:00:00.000-07:00</published><updated>2013-03-19T09:23:23.793-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-19T09:23:23.793-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>Solving Boggle with Dart</title><content type="html">My friends at work and I have been playing a lot of Scramble with Friends. It's a "tile based word searching game" where you find words on a 4x4 grid of letters. Being a good Dart hacker, I wanted to try writing a small library to find all possible words on the board. Here's how I did it!&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-NgEX7-t-63E/UUf_0JAbSiI/AAAAAAAAVWM/zNF3HZWDdgA/s1600/Screen+Shot+2013-03-18+at+11.04.27+PM.png" style="margin-left: auto; margin-right: auto;" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Dart, not trad. :)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
First off, props to &lt;a href="http://danvk.org/"&gt;danvk.org&lt;/a&gt; and his helpful posts (such as this &lt;a href="http://www.danvk.org/wp/2007-02-01/tries-the-perfect-data-structure/" target="_blank"&gt;one&lt;/a&gt;) on solving Boggle.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Old 'n busted&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
My first attend was the naive version. The following code simply tried every possible combination, in a depth-first search. It works, but it's slow. So very slow.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #f0f0f0; border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; width: 450.828125px;"&gt;&lt;code style="word-wrap: normal;"&gt;class Solver {  
  final Map _words;  
  final List&amp;lt;List&amp;lt;String&amp;gt;&amp;gt; _grid;  
  final List&amp;lt;List&amp;gt; _visited = new List.generate(4, (_) =&amp;gt; new List.filled(4, false));  
  final List _found = new List();  
    
  Solver(this._words, this._grid);  
    
  _solve(int x, int y, [String word = '']) {  
   _visited[x][y] = true;  
     
   final newWord = '${word}${_grid[x][y]}';  
     
   if (_words.containsKey(newWord)) {  
    _found.add(newWord);  
   }  
     
   for (var _x = -1; _x &amp;lt; 2; _x++) {  
    final nX = x + _x;  
    if (nX &amp;lt; 0 || nX &amp;gt; 3) continue;  
    for (var _y = -1; _y &amp;lt; 2; _y++) {  
     if (_x == 0 &amp;amp;&amp;amp; _y == 0) continue;  
     final nY = y + _y;  
     if (nY &amp;lt; 0 || nY &amp;gt; 3) continue;  
     if (_visited[nX][nY] == true) continue;  
     _solve(nX, nY, newWord);  
    }  
   }  
     
   _visited[x][y] = false;  
  }  
    
  Iterable&amp;lt;String&amp;gt; findAll() {  
   for (var x = 0; x &amp;lt; 4; x++) {  
    for (var y = 0; y &amp;lt; 4; y++) {  
     _solve(x, y);  
    }  
   }  
     
   return _found;  
  }  
 }  &lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Some notes for the code above:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Real classes!&lt;/li&gt;
&lt;li&gt;Use _ to mark names as private to the library.&lt;/li&gt;
&lt;li&gt;Final variables can't be reassigned after they are initialized. This leads to safer code.&lt;/li&gt;
&lt;li&gt;The third parameter to _solve is an "optional positional parameter". It has a default value of an empty string.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Full recursion across all possible combinations?!? Surely we can do better!&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;New hotness&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Enter a data structure called a &lt;a href="http://en.wikipedia.org/wiki/Trie" target="_blank"&gt;Trie&lt;/a&gt;. A trie is an efficient data structure for dictionaries, because the nodes in the tree are letters that spell words.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-Xx70UJTNO5M/UUgAeRhV2-I/AAAAAAAAVWU/Whf0e65Jo9o/s1600/500px-Trie_example.png" style="margin-left: auto; margin-right: auto;" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;From&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/File:Trie_example.svg"&gt;http://en.wikipedia.org/wiki/File:Trie_example.svg&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
Here is the code I used for the Trie. Thanks to &lt;a href="https://plus.google.com/110742501143171151210/posts" target="_blank"&gt;Ladislav Thon&lt;/a&gt; for the &lt;a href="https://github.com/Ladicek/dart-trie" target="_blank"&gt;initial inspiration&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #f0f0f0; border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; width: 450.828125px;"&gt;&lt;code style="word-wrap: normal;"&gt;library trie;  
   
 import 'dart:collection';  
   
 class Trie&amp;lt;T&amp;gt; {  
  T value;  
  final Map&amp;lt;int, Trie&amp;lt;T&amp;gt;&amp;gt; map;  
   
  Trie() : map = new Map&amp;lt;int, Trie&amp;lt;T&amp;gt;&amp;gt;();  
   
  T operator [](String key) {  
   var node = this;  
   for (int i = 0; i &amp;lt; key.length; i++) {  
    int char = key.codeUnitAt(i);  
   
    node = node.map[char];  
    if (node == null) {  
     return null;  
    }  
   }  
   return node.value;  
  }  
    
  Trie&amp;lt;T&amp;gt; nodeFor(String character) {  
   return map[character.codeUnitAt(0)];  
  }  
   
  void operator []=(String key, T value) {  
   var node = this;  
   for (int i = 0; i &amp;lt; key.length; i++) {  
    int char = key.codeUnitAt(i);  
   
    var current = node;  
    node = node.map[char];  
    if (node == null) {  
     current.map[char] = node = new Trie&amp;lt;T&amp;gt;();  
    }  
   }  
   node.value = value;  
  }  
 }  &lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
A couple notes about the code above:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;A trie is a tree of strings to values, so I use Dart's generics (aka parameterized types) to clearly annotate that a Trie can hold a specific kind of value &lt;i&gt;T&lt;/i&gt;&amp;nbsp;(to be specified by the consumer of this trie).&lt;/li&gt;
&lt;li&gt;Dart classes can define [], the index access operator.&lt;/li&gt;
&lt;li&gt;Dart supports libraries, so I placed this code into its own library.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Here is the new Solver, that uses the Trie:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre style="background-color: #f0f0f0; border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; width: 450.828125px;"&gt;&lt;code style="word-wrap: normal;"&gt; library solver;  
   
 import 'dart:math';  
 import 'package:tilebasedwordsearch/trie.dart';  
 export 'package:tilebasedwordsearch/trie.dart' show Trie;  
   
 class Solver {  
  final Trie _words;  
  final List&amp;lt;List&amp;lt;String&amp;gt;&amp;gt; _grid;  
  final List&amp;lt;List&amp;gt; _visited = new List.generate(4, (_) =&amp;gt; new List.filled(4, false));  
  final List _found = new List();  
    
  Solver(this._words, this._grid);  
    
  _solve(int x, int y, Trie inProgress) {  
     
   final Trie nextStep = inProgress.nodeFor(_grid[x][y]);  
     
   if (nextStep != null) {  
    if (nextStep.value != null) {  
     // FIXME: add real word  
     _found.add(nextStep.value);  
    }  
   
    _visited[x][y] = true;  
      
    for (var _x = -1; _x &amp;lt; 2; _x++) {  
     final nX = x + _x;  
     if (nX &amp;lt; 0 || nX &amp;gt; 3) continue;  
     for (var _y = -1; _y &amp;lt; 2; _y++) {  
      if (_x == 0 &amp;amp;&amp;amp; _y == 0) continue;  
      final nY = y + _y;  
      if (nY &amp;lt; 0 || nY &amp;gt; 3) continue;  
      if (_visited[nX][nY] == true) continue;  
      _solve(nX, nY, nextStep);  
     }  
    }  
   
    _visited[x][y] = false;  
   }  
     
  }  
    
  Iterable&amp;lt;String&amp;gt; findAll() {  
   for (var x = 0; x &amp;lt; 4; x++) {  
    for (var y = 0; y &amp;lt; 4; y++) {  
     _solve(x, y, _words);  
    }  
   }  
     
   return _found;  
  }  
 }  &lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
The real interesting part to me is that the Trie can act as the dictionary as well as the "in progress" tracking. As the solver walks through the tiles on the board, it looks to see if the current node in the tree has a child node for the adjacent tile. If not, the solver simply bails out immediately. No more searching all possible combinations! The new implementation above also does not build the potential word by concatenating strings, character by character. Instead, it just walks the tree until it it finds a word (the word is stored as a value on the left node) or a dead-end.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;In action&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Here's how I use it in a very simple web app. I was mostly concerned about benchmarks, so there's no UI.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #f0f0f0; border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; width: 450.828125px;"&gt;&lt;code style="word-wrap: normal;"&gt; import 'dart:html';  
 import 'package:tilebasedwordsearch/solver.dart';  
   
 main() {  
  var timeToParseFiles = query("#time-to-parse-file");  
  var numWords = query('#num-words');  
  var resultsWords = query('#results-words');  
  var resultsLength = query('#results-length');  
  var time = query('#time');  
    
  const List&amp;lt;List&amp;lt;String&amp;gt;&amp;gt; grid = const [  
   const ['A', 'B', 'C', 'D'],  
   const ['E', 'F', 'G', 'H'],  
   const ['I', 'J', 'K', 'L'],  
   const ['M', 'N', 'O', 'P']  
  ];
    
  Trie words = new Trie();  
    
  HttpRequest.getString("../assets/dictionary.txt")  
   .then((contents) {  
    var start = window.performance.now();  
    contents.split("\n").forEach((line) =&amp;gt; words[line] = line);  
    var stop = window.performance.now();
    var readFilesTime = stop - start; 
      
    var solver = new Solver(words, grid);  
      
    start = window.performance.now();  
    List&amp;lt;String&amp;gt; results = solver.findAll().toList();  
    stop = window.performance.now();
    var findAllTime = stop - start;  
      
    timeToParseFiles.text = '$readFilesTime';  
    resultsWords.text = '$results';  
    resultsLength.text = '${results.length}';  
    time.text = 'Found in $findAllTime ms';  
   })  
   .catchError((e) =&amp;gt; print(e));  
 }  &lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
The above Solver and Trie runs in about 1ms on my local machine (finding 33 words in the test board, using my dictionary), which is good enough for me. This is very much a fun weekend project, not meant to be production code. Hopefully it helps you learn a bit of Dart!&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/qpEEMxOI1ao" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/774837463202951120/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=774837463202951120&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/774837463202951120?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/774837463202951120?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/qpEEMxOI1ao/solving-boggle-with-dart.html" title="Solving Boggle with Dart" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-NgEX7-t-63E/UUf_0JAbSiI/AAAAAAAAVWM/zNF3HZWDdgA/s72-c/Screen+Shot+2013-03-18+at+11.04.27+PM.png" height="72" width="72" /><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2013/03/solving-boggle-with-dart.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUDQnk8fyp7ImA9WhBQE00.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-8233201787874472562</id><published>2013-03-14T13:20:00.003-07:00</published><updated>2013-03-14T17:27:53.777-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-14T17:27:53.777-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>I Shrunk my Dart-to-JS code by 11X and So Can You</title><content type="html">&lt;a href="http://www.dartlang.org/" target="_blank"&gt;Dart&lt;/a&gt;, the structured and scalable programming language for web apps, compiles to JavaScript thanks to &lt;a href="http://www.dartlang.org/docs/dart2js/" target="_blank"&gt;dart2js&lt;/a&gt;. This means Dart apps run across the modern web. When you compile to JavaScript, you want to ensure dart2js generates the smallest amount of bytes. Less bytes means smaller bandwidth bills, and faster load times, and longer battery life. All good things! Read on to learn how to minify your generated JavaScript.&lt;br /&gt;
&lt;br /&gt;
For this example, I will use the &lt;a href="https://github.com/sethladd/lawndart/tree/master/example/todo" target="_blank"&gt;offline-enabled Todo app&lt;/a&gt; that I built to highlight &lt;a href="https://github.com/sethladd/lawndart" target="_blank"&gt;Lawndart&lt;/a&gt;, my easy library for browser storage. The Todo app uses quite a few libraries:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;dart:html&lt;/li&gt;
&lt;li&gt;Lawndart&lt;/li&gt;
&lt;li&gt;WebSQL&lt;/li&gt;
&lt;li&gt;IndexedDB&lt;/li&gt;
&lt;li&gt;Local storage&lt;/li&gt;
&lt;li&gt;Web UI&lt;/li&gt;
&lt;/ul&gt;
The original generated JavaScript output size was 612,249 bytes. Minified, it became 289,840 bytes. Minified and gzipped it became 56,496 bytes. &lt;b&gt;That's about 11X smaller than the original output!&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
(Measuring the original size of the code is tricky. Do I count the lines that I wrote? Do I count the lines generated by the Web UI compiler? I count 9,313 bytes of generated Dart code from the Web UI compiler, which is the code that would be shipped down to Dartium during development. This does &lt;b&gt;not&lt;/b&gt;&amp;nbsp;count the size of the packages required. Also, most developers would run a tree-shaking tool on the Dart code if they want to ship pure Dart in production. When I ran dart2dart to generate a single file that contained all the Dart code required for the app, I ended up with&amp;nbsp;44,860 bytes unminified and ungzipped.)&lt;br /&gt;
&lt;br /&gt;
Let's learn how to get compiled JavaScript output as small as possible.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Step One: Turn on Minification&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The editor does not ship with minification turned on by default. Say what?! Fear not, we can fix that.&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Right click on your project&lt;/li&gt;
&lt;li&gt;Select properties&lt;/li&gt;
&lt;li&gt;Select Dart Settings&lt;/li&gt;
&lt;li&gt;Add --minify to "Additional flags:"&lt;/li&gt;
&lt;li&gt;Embrace the smallification&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
See this in action:&lt;/div&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="" frameborder="0" height="480" src="http://www.youtube.com/embed/ndOycltKKbs" width="640"&gt;&lt;/iframe&gt;

&lt;br /&gt;
&lt;br /&gt;
(Here's a &lt;a href="https://code.google.com/p/dart/issues/detail?id=8751" target="_blank"&gt;bug&lt;/a&gt; that requests to make this easier, please star!)&lt;br /&gt;
&lt;br /&gt;
If you don't use Dart Editor, you can also minify from the command line. Here is an example:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;dart2js --minify --out=app.js app.dart&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The file shrinks to&amp;nbsp;289,840 bytes with minification, a 2.1X shrinkage!&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Step Two: Compress the file on-the-fly&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Most web servers will compress your files for you, on the fly! See your web server's configuration for more details.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://httpd.apache.org/docs/2.2/mod/mod_deflate.html" target="_blank"&gt;Adding gzip to Apache&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://wiki.nginx.org/HttpGzipModule" target="_blank"&gt;Adding gzip to nginx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/appengine/kb/general#compression" target="_blank"&gt;Adding gzip to App Engine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
The file shrinks to&amp;nbsp;56,496 bytes with gzip, a 11X shrinkage from the original!&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Step Three: There is no step three!&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Yup, just use &lt;span style="font-family: Courier New, Courier, monospace;"&gt;--minify&lt;/span&gt; with dart2js and be sure your server has turned on compression/gzip.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
To be sure, we're not yet happy with the output size and we're working hard to generate even smaller code. However, minification really helps and you should use it today. Please file bugs and feature requires at &lt;a href="http://dartbug.com/"&gt;dartbug.com&lt;/a&gt;. Thanks!&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/An264B-I-q8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/8233201787874472562/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=8233201787874472562&amp;isPopup=true" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/8233201787874472562?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/8233201787874472562?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/An264B-I-q8/i-shrunk-my-dart-to-js-code-by-11x-and.html" title="I Shrunk my Dart-to-JS code by 11X and So Can You" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/ndOycltKKbs/default.jpg" height="72" width="72" /><thr:total>3</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2013/03/i-shrunk-my-dart-to-js-code-by-11x-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0EBQnY_fyp7ImA9WhBREUs.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-3282524093128435159</id><published>2013-02-18T21:52:00.004-08:00</published><updated>2013-03-01T10:14:13.847-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-01T10:14:13.847-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>Exploring Dart's Async Library</title><content type="html">(Warning: work in progress...)&lt;br /&gt;
&lt;br /&gt;
Use Dart's async library to keep work off the main UI thread and help your users have a smooth and performant experience. The dart:async library contains classes for timers, futures, streams, and more. Effective use of dart:async keeps your apps easier to understand and your UI snappy.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-Ask4j5r7YN0/USMKsji52CI/AAAAAAAAPYQ/g1_wv2aT2Ys/s1600/5911302478_36e0840d54.jpg" style="margin-left: auto; margin-right: auto;" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Telling the future is easier when you have all the data.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2&gt;
&lt;span style="font-size: large;"&gt;
The event loop&lt;/span&gt;&lt;/h2&gt;
&lt;br /&gt;
Or, why this all matters.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Dart programs, just like JavaScript, have no shared-state threads.&lt;/b&gt; The UI and the program use the same thread of execution, so when the UI is updating the program isn't running. Conversely, when the programming is running, the UI isn't updating. Keeping work off of the main thread means more time for the UI to respond to user input, which means the UI feels snappy and responsive.&lt;br /&gt;
&lt;br /&gt;
The runtime maintains an event loop and a queue of work to perform. &lt;b&gt;The event loops pops work items off of the queue, one after another. While one work item is handled, the other work items sit in the queue patiently.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Examples of work items can include callbacks for mouse move, mouse click, scroll events, database fetches, window resizes, and programatic callbacks. That is, all of the events and callbacks registered by your program or generated by the browser end up in the queue to be processed by the event loop. It's clear that &lt;b&gt;keeping the individual work items small is key&lt;/b&gt; to a performant application and UI.&lt;br /&gt;
&lt;br /&gt;
(Note, in Dart you can create new isolates if you want concurrent program execution. In JavaScript, you can create new Web Workers to achieve the same effect.)&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Async programming&lt;/h2&gt;
&lt;br /&gt;
As an analogy, consider these two scenarios:&lt;br /&gt;
&lt;br /&gt;
1) Send an email, stop doing any work at all until you hear a response.&lt;br /&gt;
2) Send an email, continue on your day and handle the response when you get it.&lt;br /&gt;
&lt;br /&gt;
Scenario #1 is synchronous. Scenario #2 is asynchronous.&lt;br /&gt;
&lt;br /&gt;
Here is an example of a synchronous API:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; print('at the beginning');  
 var file = new File('config.txt');  
 var contents = file.readAsStringSync(); // program blocks until all contents are read  
 print(contents);  
 print('at the end');  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
This program will print:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;at the beginning&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;[config file contents]&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;at the end&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The above code runs as you would expect, line by line. The file contents can be used immediately in the line after readAsStringSync().&lt;br /&gt;
&lt;br /&gt;
However, if the file is large, the entire program is blocked waiting for the file to be read into memory. For simple command-line scripts this is usually acceptable, but for client-side apps or for server programs, blocking is totally not cool. Surely, we can do better!&lt;br /&gt;
&lt;br /&gt;
To write responsive and asynchronous programs, you should not block on work but instead ask to be notified when the work is complete. Here is an example of an asynchronous API:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; print('at the beginning');  
 var file = new File('config.txt');  
 Future future = file.readAsString(); // returns immediately  
 future.then((String contents) {  
  print(contents); // prints only when the file contents are ready  
 });  
 print('at the end');  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
This program will print:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;at the beginning&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;at the end&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;[config file contents]&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
On the first event loop iteration, three things happen:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;print 'at the beginning'&lt;/li&gt;
&lt;li&gt;queue up work to read the file contents&lt;/li&gt;
&lt;li&gt;print 'at the end'&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
When the file is completely read into memory:&lt;/div&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;The future's callback is fired with the file contents as the value&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
As you can see, printing the file contents happens "in the future". The program is not blocked waiting for the file to be read, as demonstrated by 'at the end' printed before the file contents.&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
As an aside, you could write the code like this:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; print('at the beginning');  
 var file = new File('config.txt');  
 file.readAsString().then((String contents) {  
  print(contents); // prints only when the file contents are ready  
 });  
 print('at the end');  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Or even more simply:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; print('at the beginning');  
 var file = new File('config.txt');  
 file.readAsString().then(print);  
 print('at the end');  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
To summarize, asynchronous programming is the art of not blocking the main thread. Writing an asynchronous program can be tricky, because the program doesn't execute in what seems to be linear order. Strong abstractions and object models can help put an object-oriented interface on top of hard-to-follow asynchronous code.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h2&gt;
The dart:async library&lt;/h2&gt;
&lt;br /&gt;
To help manage asynchronous programs, Dart bundles the dart:async library. Inside, you will find:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Future, for handling values returned later&lt;/li&gt;
&lt;li&gt;Completer, to help create and finish Futures&lt;/li&gt;
&lt;li&gt;Timer, for repeating tasks, and tasks scheduled for later&lt;/li&gt;
&lt;li&gt;Stream, for streams of events&lt;/li&gt;
&lt;li&gt;StreamController, to help create and manage a stream&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Let's take a look at each of these classes.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
Future and Completer, aka Producing values from the future&lt;/h3&gt;
&lt;div&gt;
&lt;br /&gt;
If an asynchronous method or function returns a single value (e.g. readAsString() returns one thing, the file contents), it should return a Future. A Future represents a value not yet available, with the expectation that the value will be available in the future. If a function needs to perform some work before generating a value, the function should return a Future instead of taking a callback parameter.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
A Completer can help manage the creation, and completion, of a future value. It is recommended to use a Completer, instead of trying to work with a raw Future.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Here is an example method that uses a Completer to return and complete a Future.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; Future&amp;lt;Account&amp;gt; getAccount(String id) {  
  var completer = new Completer();  
  database.query('SELECT id FROM accounts', (results) {  
   var account = new Account.fromDb(results.first);  
   completer.complete(account);  
  }, (error) =&amp;gt; completer.completeError(error));  
  return completer.future;  
 }  
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;
(Note, the database API is fictional.)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The database.query() method takes a SQL query and a callback function to handle any results. Thanks to lexical scope, the callback has access to the completer, so it can complete the future with the expected value.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The second callback is run when the database driver encounters an error. Notice how you can complete a Future with an error. If you create a future, be sure to complete it with either a value or an error.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The getAccount() method immediately returns the completer's future, before it queries the database. Sometime in the future, after all the network I/O and database protocol handling, the results are generated and the the completer completes.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
When a completer completes, the future generated by the completer gets a value, and code waiting for a value is notified.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
A client can use the getAccount() method like this:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; Future future = getAccount('234532');  
 future  
  .then((account) =&amp;gt; account.login())  
  .catchError((e) =&amp;gt; print(e));  
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;
Notice how catchError() is chained off of then(). This works because then() actually returns a Future.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
Creating futures with values that exist now&lt;/h3&gt;
&lt;div&gt;
&lt;br /&gt;
Sometimes, you need to conform a synchronous API to an asynchronous API. That is, you might have a value available right now, however you need to wrap it in a Future. Luckily, there's a constructor for that.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Use new Future.immediate(value) to create a future whose value is available on the next event-loop iteration. Here is an example:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; Future&amp;lt;bool&amp;gt; isOnline() {  
  return new Future.immediate(true);  
 }  
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;
It's rare that you have the value immediately available, especially when the API was originally designed to be asynchronous. Another use for immediate is to push the work that would be done on a value to the next event-loop cycle.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Similar to Future.immediate() is Future.of(), which runs a function, collects the result, and makes it available on the next event-loop iteration. Here is an example:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; bool checkConnection() {  
  // ...  
 }  
   
 Future&amp;lt;bool&amp;gt; isOffline() {  
  return new Future.of(checkConnection);  
 }  
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;
The function is run now, but the value isn't made available until the next event-loop iteration.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
If you have a value available now, but you want to delay the completion of a Future, you can use Future.delayed(). The value is generated now, but the future waits before completing. Here is an example:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; Future simulateNetworkLatency(int delayMillis) {  
  return new Future.delayed(delayMillis, () =&amp;gt; makeRandomBytes());  
 }  
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;
If an error occurred, and you need to immediately complete a Future with an error, you can use Future.immediateError.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; Future isOnline() {  
  if (!isConnected) {  
   return new Future.immediateError(new StateError('not connected'));  
  } else {  
   return new Future.immediate(true);  
  }  
 }  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
The above code is rare, most of the time a function that returns a Future is also interacting with an asynchronous API.&lt;br /&gt;
&lt;br /&gt;
Protip: Always return a Future from a method that uses a Future. This allows the calling code to properly catch errors that might occur.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Consuming Futures&lt;/h3&gt;
&lt;div&gt;
&lt;br /&gt;
The previous section looked at producing a Future, either with a Completer or with the various constructors on Future. This section will focus on consuming Futures produced by an API.&lt;br /&gt;
&lt;br /&gt;
Tip: To learn more about the basics of consuming Futures, read &lt;a href="http://www.dartlang.org/articles/using-future-based-apis/" target="_blank"&gt;Using Future based APIs&lt;/a&gt; from dartlang.org.&lt;br /&gt;
&lt;br /&gt;
For robust &lt;i&gt;synchronous&lt;/i&gt; code, you should expect and handle errors. Here is a typical example:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #f0f0f0; border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; width: 450.828125px;"&gt;&lt;code style="word-wrap: normal;"&gt; DatabaseConnection db;  
 try {  
  db = openDatabase();  
  var results = db.query();  
 } catch (e) {  
  print(e);  
 } finally {  
  if (db != null) db.close();  
 }&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
The intended code runs inside the try block, errors and exceptions are handled inside the catch block, and the finally block is run no matter what.&lt;br /&gt;
&lt;br /&gt;
You can achieve the same type of code organization with Future-based asynchronous code. Here is an example:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #f0f0f0; border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; width: 450.828125px;"&gt;&lt;code style="word-wrap: normal;"&gt; DatabaseConnection db;  
 Future future = openDatabase();  
 future  
  .then((_db) {  
   db = _db;  
   db.query();  
  })  
  .catchError(print)  
  .whenComplete(() =&amp;gt; if (db != null) db.close()); &lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
In the above example, the intended code runs inside then(), errors and exceptions are handled inside catchError(), and whenComplete() is run no matter what.&lt;br /&gt;
&lt;br /&gt;
It's very important to chain catchError() and whenComplete() from the original future object. Do not do this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #f0f0f0; border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; width: 450.828125px;"&gt;&lt;code style="word-wrap: normal;"&gt; // bad, don't do this  
 Future future = openDatabase();  
 future.then((_) =&amp;gt; /* ... */);  
 // this only catches errors from openDatabase(), not from then()  
 future.catchError(print);  &lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
The above example will not catch errors thrown by then(). You must chain then(), catchError(), and whenComplete() to full handle errors.&lt;br /&gt;
&lt;br /&gt;
You can chain Futures if you want them to run in order, one after another. Here is an example:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #f0f0f0; border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; width: 450.828125px;"&gt;&lt;code style="word-wrap: normal;"&gt; db.open()  
  .then((_) =&amp;gt; db.nuke())  
  .then((_) =&amp;gt; db.save("world", "hello"))  
  .then((_) =&amp;gt; db.save("is fun", "dart"))  
  .then((_) =&amp;gt; db.getByKey("hello"))  
  .then((value) =&amp;gt; query('#text').text = value)  
  .catchError((e) =&amp;gt; print(e)); &lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Notice how there is one catchError() at the end of the chain. The last catchError() handles any error or exception thrown from anywhere in the chain.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
[Moe coming soon!]&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: xx-small;"&gt;(Photo credit:&amp;nbsp;&lt;a href="http://www.flickr.com/photos/49848582@N08/5911302478/"&gt;http://www.flickr.com/photos/49848582@N08/5911302478/&lt;/a&gt;, CC)&lt;/span&gt;&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/hxMaeZSJKzY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/3282524093128435159/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=3282524093128435159&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/3282524093128435159?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/3282524093128435159?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/hxMaeZSJKzY/exploring-darts-async-library.html" title="Exploring Dart's Async Library" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-Ask4j5r7YN0/USMKsji52CI/AAAAAAAAPYQ/g1_wv2aT2Ys/s72-c/5911302478_36e0840d54.jpg" height="72" width="72" /><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2013/02/exploring-darts-async-library.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEDQHo7fCp7ImA9WhBTGEU.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-294688656255786622</id><published>2013-02-14T16:21:00.001-08:00</published><updated>2013-02-14T16:21:11.404-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-02-14T16:21:11.404-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>Lawndart helps you write offline web apps</title><content type="html">I'm happy to announce my new &lt;a href="https://github.com/sethladd/lawndart" target="_blank"&gt;Lawndart&lt;/a&gt; library for Dart, which helps you build offline-enabled modern web apps. Using Lawndart, you can use a consistent and easy interface no matter what underlying storage mechanism is supported.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-kn27mgYAfsc/UR1swCO2hNI/AAAAAAAAPVw/mIHWI9g-vvY/s1600/751661958_79b4ea4709.jpg" style="margin-left: auto; margin-right: auto;" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;These things are seriously dangerous. The toy, not the source code.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;div&gt;
Lawndart was initially inspired by &lt;a href="http://brian.io/lawnchair/" target="_blank"&gt;lawnchair&lt;/a&gt;, a JavaScript library that helps to provide a consistent interface across client-side storage. However, Lawndart evolved and adopted a Future based API for more&amp;nbsp;composable&amp;nbsp;methods.&lt;br /&gt;
&lt;br /&gt;
Available in version 0.2.0:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Unified API for in-memory, local storage, indexed db, and websql&lt;/li&gt;
&lt;li&gt;Future-based APIs&lt;/li&gt;
&lt;li&gt;Tests&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/sethladd/lawndart/tree/master/example/todo" target="_blank"&gt;Example Web UI app&lt;/a&gt; with IndexedDB&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Here is an example of using Lawndart to open, clear, save, and retrieve data:&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; var store = new IndexedDbAdapter('teststore', 'testdb');  
 store.open()  
  .then((_) =&amp;gt; store.nuke())  
  .then((_) =&amp;gt; store.save(id, "hello"))  
  .then((_) =&amp;gt; store.save("is fun", "dart"))  
  .then((_) =&amp;gt; store.getByKey("hello"))  
  .then((value) =&amp;gt; query('#$id').text = value);  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Thanks to Futures, the APIs can be chained. All methods in Lawndart return a Future for asynchronous&amp;nbsp;behavior.&lt;br /&gt;
&lt;br /&gt;
You can &lt;a href="http://pub.dartlang.org/packages/lawndart" target="_blank"&gt;install Lawndart from pub&lt;/a&gt;, Dart's package manager. Simply add a dependency to lawndart in your pubspec.yaml file:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; name: your_cool_app  
 dependencies:  
  lawndart: any  &lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Lawndart is open source and &lt;a href="https://github.com/sethladd/lawndart" target="_blank"&gt;hosted on Github&lt;/a&gt;. Pull requests are much appreciated, as are bugs and feature requests.&lt;br /&gt;
&lt;br /&gt;
Please try Lawndart and let me know what you think!&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: xx-small;"&gt;Photo Credit: &lt;a href="http://www.flickr.com/photos/9049309@N05/751661958/"&gt;im.no.hero&lt;/a&gt; &lt;a href="http://creativecommons.org/licenses/by-nc-nd/2.0/"&gt;cc&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/lNfIPVy6a5k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/294688656255786622/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=294688656255786622&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/294688656255786622?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/294688656255786622?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/lNfIPVy6a5k/lawndart-helps-you-write-offline-web.html" title="Lawndart helps you write offline web apps" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-kn27mgYAfsc/UR1swCO2hNI/AAAAAAAAPVw/mIHWI9g-vvY/s72-c/751661958_79b4ea4709.jpg" height="72" width="72" /><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2013/02/lawndart-helps-you-write-offline-web.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEHQHk5cCp7ImA9WhBSGEk.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-4054889566625351496</id><published>2013-02-11T10:30:00.000-08:00</published><updated>2013-02-25T17:03:51.728-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-02-25T17:03:51.728-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="webcomponents" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>Slides from JFokus talk on Dart and Web Components</title><content type="html">I had the pleasure of presenting "Web Components Now: Dart and Web UI" at JFokus 2013. In this presentation, I covered the new hotness coming to the web platform and how Dart helps to bring much of to modern browsers today. Encapsulation, templates, custom elements, and dynamic data-driven views are made available thanks to Dart's Web UI library (heavily inspired by Web Components and Model-Driven Views).&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="" frameborder="0" height="360" src="http://www.youtube.com/embed/rdDoc3fLaII" width="640"&gt;&lt;/iframe&gt;

&lt;br /&gt;
The &lt;a href="http://sethladd.github.com/preso-dart-web-components/#1" target="_blank"&gt;slides&lt;/a&gt; are now available. &lt;b&gt;&lt;i&gt;WARNING&lt;/i&gt;&lt;/b&gt;: You might need &lt;a href="https://www.google.com/intl/en/chrome/browser/canary.html" target="_blank"&gt;Chrome Canary&lt;/a&gt; to see all the demos in action.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://sethladd.github.com/preso-dart-web-components/#1" target="_blank"&gt;&lt;img border="0" height="408" src="http://3.bp.blogspot.com/-060mFJhDZ_4/URWrAhnaElI/AAAAAAAAPNc/rbPXmWdKXr0/s640/Screen+Shot+2013-02-08+at+4.42.33+PM.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
In the presentation, I covered topics such as:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Web Components&lt;/li&gt;
&lt;li&gt;Shadow DOM&lt;/li&gt;
&lt;li&gt;Custom elements&lt;/li&gt;
&lt;li&gt;Dart language and libraries&lt;/li&gt;
&lt;li&gt;Dart's toolchain&lt;/li&gt;
&lt;li&gt;Dart's Web UI library (a polyfill for Web Components and MDV-esque behavior)&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
If you're interested in these topics, you can learn more about &lt;a href="http://www.dartlang.org/" target="_blank"&gt;Dart&lt;/a&gt; and &lt;a href="http://www.dartlang.org/articles/dart-web-components/" target="_blank"&gt;Web UI&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
JFokus was a blast. Great conference, friendly crowd, excellent A/V setup! As an old Java developer, it felt good showing off the hotness of modern web development and structured web languages to a "hometown" crowd. Check out this&amp;nbsp;&lt;a href="https://plus.google.com/101932012361889521527/posts/NuPUZCaxJrU" target="_blank"&gt;Photosphere pick&lt;/a&gt;&amp;nbsp;of the conference room, thanks to&amp;nbsp;&lt;a href="https://plus.google.com/101932012361889521527/posts" target="_blank"&gt;Alexis&amp;nbsp;Alexis Moussine-Pouchkine&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Thanks to everyone who came to the presentation!&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Big props to &lt;a href="https://plus.google.com/118075919496626375791/posts" target="_blank"&gt;Mr. Eric Bidelman&lt;/a&gt; for some of the slides, and the awesome &amp;lt;x-gangam-style&amp;gt; tag.&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/uCEu3QaWeQE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/4054889566625351496/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=4054889566625351496&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/4054889566625351496?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/4054889566625351496?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/uCEu3QaWeQE/slides-from-jfokus-talk-on-dart-and-web.html" title="Slides from JFokus talk on Dart and Web Components" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/rdDoc3fLaII/default.jpg" height="72" width="72" /><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2013/02/slides-from-jfokus-talk-on-dart-and-web.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUNSH0zfyp7ImA9WhBTE0s.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-2006119771539984180</id><published>2013-02-08T14:24:00.004-08:00</published><updated>2013-02-08T14:24:59.387-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-02-08T14:24:59.387-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>Bite-sized Dart videos</title><content type="html">For the past month I've been working with &lt;a href="http://www.marakana.com/" target="_blank"&gt;Marakana&lt;/a&gt; to film and produce short, bite-sized introduction videos for the Dart language and libraries. After filming lots of various videos and formats, I've noticed that viewer retention is difficult. It's so easy to simply click away at any time. Our long-form videos are difficult to watch all the way through. So, we're swinging over to the other end of the spectrum with super-short, targeted videos. The result: &lt;a href="http://www.dartlang.org/dart-tips/" target="_blank"&gt;Dart Tips&lt;/a&gt;, for when you have only 5 minutes to learn something new about &lt;a href="http://www.dartlang.org/" target="_blank"&gt;Dart&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img border="0" height="348" src="http://3.bp.blogspot.com/-6paRIn_Dt-w/URV6F6CUwaI/AAAAAAAAPMo/wqNjok_3cCw/s640/Screen+Shot+2013-02-08+at+2.19.49+PM.png" style="margin-left: auto; margin-right: auto;" width="640" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;From "&lt;a href="http://www.youtube.com/watch?v=DWtvhdJkiRE&amp;amp;list=PLndbWGuLoHeaPgfKYlwJvDDxCrRdDbga3&amp;amp;index=6" target="_blank"&gt;Functions are Fun, pt 1&lt;/a&gt;"&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
Six videos have been released so far. Topics include:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=g09UVKyYfIs&amp;amp;list=PLndbWGuLoHeaPgfKYlwJvDDxCrRdDbga3&amp;amp;index=1" target="_blank"&gt;Reading a Dart script&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=CfRFixQTJWA&amp;amp;list=PLndbWGuLoHeaPgfKYlwJvDDxCrRdDbga3&amp;amp;index=2" target="_blank"&gt;Dart runtime modes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=-LmD0hghGjo&amp;amp;list=PLndbWGuLoHeaPgfKYlwJvDDxCrRdDbga3&amp;amp;index=4" target="_blank"&gt;Built-in types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=_td6qXi_GmA&amp;amp;list=PLndbWGuLoHeaPgfKYlwJvDDxCrRdDbga3&amp;amp;index=3" target="_blank"&gt;Variables&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=Mdlnx4cl014&amp;amp;list=PLndbWGuLoHeaPgfKYlwJvDDxCrRdDbga3&amp;amp;index=5" target="_blank"&gt;Collections&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=DWtvhdJkiRE&amp;amp;list=PLndbWGuLoHeaPgfKYlwJvDDxCrRdDbga3&amp;amp;index=6" target="_blank"&gt;Functions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
You can see the entire &lt;a href="http://www.youtube.com/playlist?list=PLndbWGuLoHeaPgfKYlwJvDDxCrRdDbga3" target="_blank"&gt;playlist for Dart Tips&lt;/a&gt;&amp;nbsp;for all the episodes.&lt;br /&gt;
&lt;br /&gt;
For a taste, here's "Functions are fun, pt 1":&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;object width="320" height="266" class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://1.gvt0.com/vi/DWtvhdJkiRE/0.jpg"&gt;&lt;param name="movie" value="http://www.youtube.com/v/DWtvhdJkiRE&amp;fs=1&amp;source=uds" /&gt;&lt;param name="bgcolor" value="#FFFFFF" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;embed width="320" height="266"  src="http://www.youtube.com/v/DWtvhdJkiRE&amp;fs=1&amp;source=uds" type="application/x-shockwave-flash" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;
&lt;br /&gt;
Marakana has been great to work with. They are professional, fun, and like to experiment with new techniques. They have a strong training operation, providing classes on Android, HTML5, and hopefully soon Dart. :)&lt;br /&gt;
&lt;br /&gt;
More videos are on their way. What do you want to see next?&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/xBPUThPXu6Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/2006119771539984180/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=2006119771539984180&amp;isPopup=true" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/2006119771539984180?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/2006119771539984180?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/xBPUThPXu6Q/bite-sized-dart-videos.html" title="Bite-sized Dart videos" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-6paRIn_Dt-w/URV6F6CUwaI/AAAAAAAAPMo/wqNjok_3cCw/s72-c/Screen+Shot+2013-02-08+at+2.19.49+PM.png" height="72" width="72" /><thr:total>6</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2013/02/bite-sized-dart-videos.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8MSH47fSp7ImA9WhNaFEU.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-675533767029261011</id><published>2013-01-29T10:41:00.001-08:00</published><updated>2013-01-29T10:41:29.005-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-01-29T10:41:29.005-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><category scheme="http://www.blogger.com/atom/ns#" term="webdev" /><title>Minification is not enough, you need tree shaking</title><content type="html">&lt;div style="text-align: center;"&gt;
&lt;span style="font-size: x-large;"&gt;&lt;i&gt;In which the virtues of automated mechanical&amp;nbsp;arboreal&amp;nbsp;pruning are&amp;nbsp;extolled&amp;nbsp;over&amp;nbsp;quaint&amp;nbsp;manual labor, as applied to web development build processes.&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;The setup&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Ever notice how the primary bit of marketing for many traditional web programming libraries is their download size? Why is that?&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Check this out:&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img alt="jQuery claims it is only 32kb minified." border="0" height="332" src="http://1.bp.blogspot.com/-D9sfrEpCgYQ/UQd_2CsOc4I/AAAAAAAAPB0/kXHsw3Pco6I/s400/Screenshot_1_28_13_11_43_PM.png" title="" width="400" /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img alt="Zepto claims it is less than a quarter the size of jQuery." border="0" height="256" src="http://2.bp.blogspot.com/-92IPW75KTrU/UQd_6WaRtlI/AAAAAAAAPB8/9QN8x7OFtAg/s400/Screenshot_1_28_13_11_45_PM.png" title="" width="400" /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img alt="Dojo claims its nano core is 3.8kb." border="0" height="190" src="http://2.bp.blogspot.com/-X9x4MGPetOk/UQeAAjIP_9I/AAAAAAAAPCE/eiPbyQpVAxA/s400/Screenshot_1_28_13_11_51_PM.png" title="" width="400" /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Why does size matter so much for these libraries? Your first instinct is probably, "because the more bytes you shuttle across the wire, the slower the app starts up." Yes, this is true. I'd also say you're wrong. The &lt;i&gt;primary&lt;/i&gt; reason that size matters for these libraries is because &lt;b&gt;traditional web development has&amp;nbsp;no intelligent or automated way to prune unused code&lt;/b&gt;&amp;nbsp;so you can ship&amp;nbsp;only the code that is used&amp;nbsp;over the wire.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;The web is full of links, yet web dev has no linker&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;The web development workflow is missing a linking step.&lt;/b&gt; A linker's job is to combine distinct project files into a single executable. A smart linker will only include the symbols and code that are actually used by the application, thus pruning unused code. The traditional web developer does not have an intelligent linker.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
It's 2013, and the job of micro-managing web development libraries is still being done by humans. Humans: the same people that brought you &lt;a href="http://en.wikipedia.org/wiki/Great_Pacific_Garbage_Patch" target="_blank"&gt;this little gem&lt;/a&gt;. &lt;b&gt;Web developers need machines and tools to take care of linking and minifying&lt;/b&gt; so they can get back to comparing traditional web development libraries based on actual feature sets instead of how femto they are.&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I want my web programming language to offer enough structure and intelligent tools to take care of pruning, minification, and more. This is why I dig &lt;a href="http://www.dartlang.org/" target="_blank"&gt;Dart&lt;/a&gt;, because it has the structure (classes, libraries, packages, type annotations, metadata, etc) and the tools (dart2js) for a modern development workflow.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Don't just prune unused code, shake it off&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Dart tools support tree shaking, a technique to "shake" off unused code&lt;/b&gt;, thus shrinking the size of the deployed application. I can import rich libraries chock full of useful goodness into my application, but &lt;b&gt;only the functions I actually use will be included in my generated output&lt;/b&gt;. Awesome!&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-QLudiPMjDrE/UQeWVmohsjI/AAAAAAAAPEY/oCP8zlJL8Ks/s1600/Dart+Tree+Shaking+(1).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="The source application goes through a tree-shaking compiler and its output is smaller." border="0" height="640" src="http://1.bp.blogspot.com/-QLudiPMjDrE/UQeWVmohsjI/AAAAAAAAPEY/oCP8zlJL8Ks/s640/Dart+Tree+Shaking+(1).png" title="" width="636" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Real code example, shaken not stirred&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Consider this simple Dart library, ironically named &lt;i&gt;embiggen.&amp;nbsp;&lt;/i&gt;There are two top-level functions in this library,&amp;nbsp;&lt;i&gt;embiggen&lt;/i&gt;&amp;nbsp;and&amp;nbsp;&lt;i&gt;unembiggen&lt;/i&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; library embiggen;  
   
 String embiggen(String msg) {  
  if (msg == null) {  
   throw new ArgumentError("must not be null");  
  }  
    
  return msg.toUpperCase();  
 }  
   
 String unembiggen(String msg) {  
  if (msg == null) {  
   throw new ArgumentError("must not be null");  
  }  
    
  return msg.toLowerCase();  
 }  &lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;
Here is the main program, which uses &lt;b&gt;only&lt;/b&gt; embiggen:&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; import 'package:embiggen/embiggen.dart';  
   
 main() {  
  var args = new Options().arguments;  
  if (args.length == 0) {  
   print("Usage: dart embiggen.dart phrase");  
   return;  
  }  
    
  var phrase = args[0];  
    
  print(embiggen(phrase));  
 }  
   
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;
I love embiggen, but I'm less entralled with unembiggen and will never use it. Do I have to search for nano-embiggen?! Nay! Let the linker do it's tree-shaking magic.&lt;br /&gt;
&lt;br /&gt;
Run the main application through the dart2js tool, which supports tree-shaking for both JavaScript and Dart outputs. Note there is no command-line option for tree shaking, because dart2js is always tree shaking. For simplicity's sake, let's generate Dart.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; dart2js --output-type=dart embiggen.dart  
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;
Gaze into the tree-shook generated output (reformatted to make it easy to read):&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt;main() {
  var args=new Options().arguments;
  if (args.length == 0) {
    print("Usage: dart embiggen.dart phrase");
    return;
  }
  var phrase=args[0];print(embiggen(phrase));
}

String embiggen(String msg) {
  if (msg == null) {
    throw new ArgumentError("must not be null");
  }
  return msg.toUpperCase();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;i&gt;(note: The actual output is actually all on one line, with white space removed. I reformatted the code above to make it easy to read.)&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Notice how the embiggen function is included, but &lt;b&gt;unembiggen is nowhere to be seen&lt;/b&gt;, even though I imported the library. The tree, it is shaken!&lt;br /&gt;
&lt;br /&gt;
But is this the best we can do? The dart2js tool also supports minification with the --minify flag.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; dart2js &lt;b&gt;--minify&lt;/b&gt; --output-type=dart embiggen.dart  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
The minified, single-line, tree-shook generated output:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; main(){var A=new Options().arguments;if(A.length==0){print("Usage: dart
embiggen.dart phrase");return;}var C=A[0];print(B(C));}
B( A){if(A==null){throw new ArgumentError("must not be null");}
return A.toUpperCase();}  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;b&gt;Both outputs have unused code eliminated, and the minified version also replaces variable names. This is exactly the kind of help I want from my tools.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Why this works&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The structure of Dart programs cannot change after compilation. In other words, Dart does not support altering class structure during runtime. Dart also does not have extreme&amp;nbsp;dynamism&amp;nbsp;like eval(). &lt;b&gt;Dart compilers and linkers can assume more about the structure of the program&lt;/b&gt;, and thus can be more aggressive about tree shaking and minifications.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Moral of the story&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I believe that &lt;b&gt;web developers need a better workflow that automates tree shaking&lt;/b&gt;, dead code elimination, minification, and more. Stop caring how big a library is, and instead let a tool or build step produce the smallest output possible for you, ideally by tree shaking the application.&lt;br /&gt;
&lt;br /&gt;
One option to consider is&amp;nbsp;&lt;a href="http://www.dartlang.org/" target="_blank"&gt;Dart&lt;/a&gt;, with its&amp;nbsp;structured language and intelligent tools, like a tree-shaking and minifying compiler. With dart2js, you can import entire libraries, regardless of size, and generate only the code that is required to run the program.&lt;br /&gt;
&lt;br /&gt;
Regardless of what language you use, demand more from your tools.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img border="0" height="260" src="http://1.bp.blogspot.com/-e9CclonRHqg/UQeQF2Fe2RI/AAAAAAAAPDs/RPFhinKX2oQ/s400/548040b489d0c5f41dd45ad7b3d5164c.png" width="400" /&gt;&amp;nbsp;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-PcvWhaJXr9g/UQeQCbQpwDI/AAAAAAAAPDk/s0DUIazFALI/s320/kelly_picking_medlar.png" width="240" /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Acknowledgements&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Thanks to Bob Nystrom's OSCON presentation from 2012, from which I humbly embraced-and-extended the setup of this post.&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/okOCiSHeifE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/675533767029261011/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=675533767029261011&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/675533767029261011?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/675533767029261011?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/okOCiSHeifE/minification-is-not-enough-you-need.html" title="Minification is not enough, you need tree shaking" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-D9sfrEpCgYQ/UQd_2CsOc4I/AAAAAAAAPB0/kXHsw3Pco6I/s72-c/Screenshot_1_28_13_11_43_PM.png" height="72" width="72" /><thr:total>2</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2013/01/minification-is-not-enough-you-need.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IERnYzeyp7ImA9WhNaFEk.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-2978307520267382699</id><published>2013-01-28T22:38:00.001-08:00</published><updated>2013-01-28T22:38:27.883-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-01-28T22:38:27.883-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>Holy Cow, Dart Unit Tests are Easy</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img border="0" src="http://3.bp.blogspot.com/-kHsWvzaUbpM/UQdmASQtEzI/AAAAAAAAPBk/62ErwVsGb_w/s1600/Screenshot_1_28_13_10_01_PM.png" /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Dart provides a rich &lt;a href="http://www.dartlang.org/articles/dart-unit-tests/"&gt;unit test library&lt;/a&gt; out of the box. Inspired by testing libraries like &lt;a href="http://http//code.google.com/p/hamcrest/"&gt;Hamcrest&lt;/a&gt; and &lt;a href="https://github.com/Ladicek/darmatch"&gt;dartmatch&lt;/a&gt;, the &lt;a href="http://api.dartlang.org/docs/bleeding_edge/unittest.html"&gt;dart:unittest library&lt;/a&gt; provides test groups, numerous matchers, and more. Read on to learn how easy it is to write your first Dart unit tests!&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img border="0" height="456" src="http://2.bp.blogspot.com/-AzbZOLpHp5Q/UQdfP6bXxVI/AAAAAAAAPA8/ClEqNIxqHrk/s640/Screen+Shot+2013-01-28+at+9.33.56+PM.png" style="margin-left: auto; margin-right: auto;" width="640" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;You, too, can create tests this pretty.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Test subject&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
To illustrate, I've just created the soon-to-be massively critical embiggen library. This library will bigify your text. It's very advanced.&lt;br /&gt;
&lt;br /&gt;
Of course, I made a &lt;a href="http://pub.dartlang.org/"&gt;pub&lt;/a&gt; package for this library:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-C3P9LhEX9OU/UQdhK8EPVAI/AAAAAAAAPBU/NaVUpGGRqfs/s1600/Screen+Shot+2013-01-28+at+9.39.50+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-C3P9LhEX9OU/UQdhK8EPVAI/AAAAAAAAPBU/NaVUpGGRqfs/s1600/Screen+Shot+2013-01-28+at+9.39.50+PM.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
The contents of embiggen.dart are:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; library embiggen;  
   
 String embiggen(String msg) {  
  if (msg == null) {  
   throw new ArgumentError("must not be null");  
  }  
    
  return msg.toUpperCase();  
 }  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
I'll let that sink in for a while, it's pretty intense.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Add the unit test package&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
You can use pub to get the unit test package and link it into your project. Simply declare the unittest dependency in your pubspec.yaml:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; name: embiggen  
 description: Turns small things into big things.  
   
 dependencies:  
  unittest: any  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Dart Editor will automatically run "pub install" when it detects a change to pubspec.yaml. If you are using the command-line tools, you can run "pub install" manually. This step will find the unittest package in your local pub cache, or it will download it from pub.dartlang.org. Once found, pub will set up the proper symlinks to make unittest available to your project.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Set up the tests&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The &lt;a href="http://pub.dartlang.org/doc/package-layout.html"&gt;pub package layout convention&lt;/a&gt; dictates that tests should be placed inside a "test" directory. Create a new file named "embiggen_test.dart" and place it inside "test".&lt;br /&gt;
&lt;br /&gt;
Import both the embiggen library and the unittest library. You need to import embiggen because your test needs to access the actual embiggen function.&lt;br /&gt;
&lt;br /&gt;
Here is embiggen_test.dart so far:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; library embiggen_test;  
   
 import 'package:embiggen/embiggen.dart';  
 import 'package:unittest/unittest.dart';  
   
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
(Note: you may need to run "pub install" again, which will configure symlinks in your "test" directory.)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Write a test&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Dart is a language without much ceremony, so let's dive into it. Create a main() function and place the first test inside. A test takes a name (or, a very short description) and an anonymous function that itself contains the test condition.&lt;br /&gt;
&lt;br /&gt;
Here is embiggen_test.dart with a simple test:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; library embiggen_test;  
   
 import 'package:embiggen/embiggen.dart';  
 import 'package:unittest/unittest.dart';  
   
 main() {  
  test("bigifies text", () {  
   expect(embiggen("hello"), equals("HELLO"));  
  });  
 }  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Use "expect(actualValue, expectedValueMatcher)" to perform the actual test. The "expectedValueMatcher" is dynamic, it can be a simple value or a matcher that can test for a wide variety of values. In the above example, equals("HELLO") returns a simple matcher that matches on equality. More on matchers shortly.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Run the test&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Choosing to place the tests inside main() was deliberate, it enables the Dart file to act as its own test runner. Simply run the embiggen_test.dart file, either from the command line or via Dart Editor.&lt;br /&gt;
&lt;br /&gt;
Here is the output on the console:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; unittest-suite-wait-for-done  
 PASS: bigifies text  
   
 All 1 tests passed.  
 unittest-suite-success  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Out of the box formatting!&lt;br /&gt;
&lt;br /&gt;
A failed test looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; unittest-suite-wait-for-done  
 FAIL: bigifies text  
  Expected: 'HELL'  
     but: was 'HELLO'.  
    
  #0   DefaultFailureHandler.fail (package:unittest/src/expect.dart:86:5)  
  #1   DefaultFailureHandler.failMatch (package:unittest/src/expect.dart:90:9)  
  #2   expect (package:unittest/src/expect.dart:55:29)  
  #3   main.&amp;lt;anonymous closure&amp;gt; (file:///Users/sethladd/dart/embiggen/test/embiggen_test.dart:8:11)  
  #4   TestCase.run (package:unittest/src/test_case.dart:83:11)  
  #5   _nextBatch._nextBatch.&amp;lt;anonymous closure&amp;gt; (package:unittest/unittest.dart:808:19)  
  #6   guardAsync (package:unittest/unittest.dart:767:19)  
    
   
 0 PASSED, 1 FAILED, 0 ERRORS  
   
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Test for exception&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Passing null to embiggen() will throw an ArgumentError, so let's not forget to test for the error condition. First, be sure to wrap the condition to test inside an anonymous function. This ensures that any exceptions thrown by the condition are properly caught. There are plenty of pre-built matchers to help with exceptions, from the simple "throws", which tests that anything was thrown, to specific matchers like "throwsArgumentError".&lt;br /&gt;
&lt;br /&gt;
Here is embiggen_test.dart with a test for an exception:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; library embiggen_test;  
   
 import 'package:embiggen/embiggen.dart';  
 import 'package:unittest/unittest.dart';  
   
 main() {  
  test("bigifies text", () {  
   expect(embiggen("hello"), equals("HELLO"));  
  });  
    
  &lt;b&gt;test("null throws ArgumentError", () {  
   expect(() =&amp;gt; embiggen(null), throwsArgumentError);  
  });&lt;/b&gt;  
 }  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;What's next&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This post barely scratches the surface. Dart's unit test library has support for setup/teardown, test groups, nested groups, a very extensive &lt;a href="http://api.dartlang.org/docs/bleeding_edge/matcher.html"&gt;matchers library&lt;/a&gt;, and even mocks/stubs. Dart also has various test outputs, ranging from VM to HTML (which you can see an example of in the top of this post).&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Further reading&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.dartlang.org/articles/dart-unit-tests/"&gt;Unit testing with Dart&lt;/a&gt;&amp;nbsp;article&lt;/li&gt;
&lt;li&gt;&lt;a href="http://shailen.github.com/blog/2012/11/19/writing-unit-tests-for-pub-packages/"&gt;Writing unit tests for pub packages in Dart&lt;/a&gt; blog post&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dartcasts.com/post/41752021557/episode-9-unit-testing-part-1-the-first"&gt;Unit test, Part 1&lt;/a&gt; screencast&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Summary&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Unit tests come out of the box with the Dart SDK. They are simple to write, compose well, and have many matchers. Simply create a "test" directory, add Dart test scripts, and BOOM you're making ice cream.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: xx-small;"&gt;(Nerd cow credit:&amp;nbsp;&lt;a href="http://www.flickr.com/photos/toastersarts/6893702709/"&gt;http://www.flickr.com/photos/toastersarts/6893702709/&lt;/a&gt;)&lt;/span&gt;&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/GKyM-0hmCD4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/2978307520267382699/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=2978307520267382699&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/2978307520267382699?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/2978307520267382699?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/GKyM-0hmCD4/holy-cow-dart-unit-tests-are-easy.html" title="Holy Cow, Dart Unit Tests are Easy" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-kHsWvzaUbpM/UQdmASQtEzI/AAAAAAAAPBk/62ErwVsGb_w/s72-c/Screenshot_1_28_13_10_01_PM.png" height="72" width="72" /><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2013/01/holy-cow-dart-unit-tests-are-easy.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQARXg_fyp7ImA9WhNbEU8.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-4912111310821532005</id><published>2013-01-12T15:50:00.000-08:00</published><updated>2013-01-13T17:35:44.647-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-01-13T17:35:44.647-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><category scheme="http://www.blogger.com/atom/ns#" term="#dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="#dart" /><title>Do This One Thing Or Your Dart Web App Will Break</title><content type="html">This is not link bait, this is a serious call to action for our Dartisans. If you do nothing, your Dart web app will stop working in a few weeks. Luckily, the fix is easy. To learn how to keep your Dart web app working, read on!&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Background&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Almost all Dart web apps use a small, but crucial, JavaScript file to bootstrap. While strictly not required, this &lt;b&gt;dart.js&lt;/b&gt; file contains the necessary logic to turn on the Dart VM, swap out Dart code for JavaScript code if the VM isn't available, enable Dart-JavaScript interop, and more.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Most Dart web apps have this line at the bottom of their HTML file:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;lt;!-- Don't do this anymore, for illustrative purposes only --&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;lt;script src="http://dart.googlecode.com/svn/branches/bleeding_edge/dart/client/dart.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;The Problem&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
There are a few problems with the current arrangement.&lt;/div&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;The Google Code SVN server is not a CDN, and is not optimized for acting as a CDN.&lt;/li&gt;
&lt;li&gt;Relying on a public HTTP link makes it impossible to work without a network connection. Hacking on Dart on a plane is difficult unless you plan ahead.&lt;/li&gt;
&lt;li&gt;The dart.js file cannot move inside the SVN repo, making it difficult to refactor directory layouts in our repository.&lt;/li&gt;
&lt;li&gt;Dart web apps start slower that normal because the SVN server is not an optimized static asset server.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
It's clear we needed to do something better, especially before Dart 1.0.&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;The Solution (aka Do This Now!)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Luckily, Dart ships out of the box with pub, our package manager. Pub helps you use third-party libraries with ease, and it turns out it works just as well with static assets like, you guessed it, JavaScript files.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
We put &lt;a href="http://pub.dartlang.org/packages/browser"&gt;dart.js into a pub package&lt;/a&gt;&amp;nbsp;named &lt;i&gt;browser&lt;/i&gt; and hosted it on pub.dartlang.org. Pub is now the canonical location for dart.js.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Step 1 - Add the browser package to your app&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Create a pubspec.yaml file for your project (if you haven't already), and add the &lt;i&gt;browser&lt;/i&gt; dependency:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;dependencies:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; browser: any&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The browser package contains the dart.js file. Learn more about the &lt;a href="http://pub.dartlang.org/doc/pubspec.html"&gt;pubspec.yaml file&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Step 2 - Run pub install&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Now run &lt;i&gt;pub install&lt;/i&gt; to download the browser package and link it to your application. This command can be run from the command line via the Dart SDK, or via Dart Editor (from the Tools menu). You'll know this works when the packages directory contains a symlink to the browser package.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Step 3 - Update links to dart.js&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Comb through your HTML files and replace:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;strike&gt;&amp;lt;script src="http://dart.googlecode.com/svn/branches/bleeding_edge/dart/client/dart.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/strike&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: inherit;"&gt;with&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;script src="packages/browser/dart.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: inherit;"&gt;&lt;b&gt;Step 4 - Put web assets into web/ (optional)&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: inherit;"&gt;The pub convention says to put all your web assets, like HTML, CSS, etc, into a web/ directory inside your pub package. Though not strictly required, we expect to be able to offer more helpful utilities if pub packages conform to conventions. Learn more about &lt;a href="http://pub.dartlang.org/doc/package-layout.html"&gt;pub package layouts&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: inherit; font-size: large;"&gt;Summary&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: inherit;"&gt;The dart.js file, probably used in your Dart web app today, will be deleted from SVN in a few weeks. You should install the browser package and update your &amp;lt;script&amp;gt; tags to point to the new location of dart.js.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: inherit;"&gt;You can &lt;a href="https://groups.google.com/a/dartlang.org/forum/?fromgroups=#!topic/misc/A7srGXHyeoQ"&gt;send feedback to the original thread on the mailing list&lt;/a&gt;, where we look forward to your comments. We know these changes are disruptive, and we appreciate your help as we refactor quickly on the road to Dart 1.0.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-family: inherit; font-size: large;"&gt;Known Issues&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-family: inherit;"&gt;Pub likes symlinks. A lot. Symlinks can be tricky to deploy, and now that dart.js is pulled in by a symlink, deployment of a Dart Web App is now a bit more complication. This is a very well know issue and we expect to have an answer for Dart web app deployments soon.&lt;/span&gt;&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/If3KVjxW0-o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/4912111310821532005/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=4912111310821532005&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/4912111310821532005?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/4912111310821532005?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/If3KVjxW0-o/do-this-one-thing-or-your-dart-web-app.html" title="Do This One Thing Or Your Dart Web App Will Break" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2013/01/do-this-one-thing-or-your-dart-web-app.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0IBSXc6fip7ImA9WhNaFEg.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-505872106414534129</id><published>2012-12-20T11:02:00.003-08:00</published><updated>2013-01-29T02:32:38.916-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-01-29T02:32:38.916-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>Video from my Dart talk at Devoxx 2012</title><content type="html">I had the pleasure of presenting &lt;a href="http://www.dartlang.org/"&gt;Dart&lt;/a&gt; to Devoxx 2012 in Antwerp, Belgium. This conference had perhaps the best A/V setup of any conference that I have been to. Bonus points: the questions at the end were excellent, the audience was clearly engaged and interested. Thanks to the organizers and all the attendees!&lt;br /&gt;
&lt;br /&gt;
Now, you can&amp;nbsp;&lt;a href="http://www.parleys.com/#st=5&amp;amp;id=3484&amp;amp;sl=50"&gt;&lt;b&gt;watch the video and slides&lt;/b&gt;&lt;/a&gt;. It's free!&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;span id="goog_1900949659"&gt;&lt;/span&gt;&lt;span id="goog_1900949663"&gt;&lt;/span&gt;&lt;span id="goog_1900949667"&gt;&lt;/span&gt;&lt;img border="0" height="345" src="http://2.bp.blogspot.com/-5EUlxjXKktY/UNNfvg7VbDI/AAAAAAAAOKc/p5CnGsHCsZA/s640/Screen+Shot+2012-12-20+at+10.57.42+AM.png" width="640" /&gt;&lt;span id="goog_1900949668"&gt;&lt;/span&gt;&lt;span id="goog_1900949664"&gt;&lt;/span&gt;&lt;span id="goog_1900949660"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/6TqLI_qWcBw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/505872106414534129/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=505872106414534129&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/505872106414534129?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/505872106414534129?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/6TqLI_qWcBw/video-from-dart-talk-at-devoxx-2012.html" title="Video from my Dart talk at Devoxx 2012" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-5EUlxjXKktY/UNNfvg7VbDI/AAAAAAAAOKc/p5CnGsHCsZA/s72-c/Screen+Shot+2012-12-20+at+10.57.42+AM.png" height="72" width="72" /><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2012/12/video-from-dart-talk-at-devoxx-2012.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cBSHc-fyp7ImA9WhNWEU8.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-8041648823099038240</id><published>2012-12-10T00:38:00.001-08:00</published><updated>2012-12-10T00:44:19.957-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-10T00:44:19.957-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="webcomponents" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>4 New Simplifications from Dart Web UI</title><content type="html">The Dart Web Components package has been renamed to Dart Web UI to better reflect the wide range of functionality found in the library. Also, syntax has been simplified based on feedback from users.&amp;nbsp;This post covers some of the new features and gives tips on how you can migrate your code.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img border="0" height="288" src="http://4.bp.blogspot.com/-ke2ObxG1ojs/UMWgaYp_VII/AAAAAAAAOJE/yZx-FwiX_p4/s320/2124673642_115fb71c69.jpg" width="320" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;A frost covered spider's web.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;a href="https://github.com/dart-lang/web-ui"&gt;Dart Web UI&lt;/a&gt; provides polyfills and compilers for Web Components (making them available to today's browsers), dynamic templates, and live data binding inspired by Model Driven Views. You can use Dart Web UI to build modern client-side web apps.&amp;nbsp;For more information, read my &lt;a href="http://blog.sethladd.com/search/label/webcomponents"&gt;blog posts about Dart Web UI&lt;/a&gt; or study the detailed &lt;a href="http://www.dartlang.org/articles/dart-web-components/"&gt;article&lt;/a&gt; on the subject.&lt;br /&gt;
&lt;div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Shorter package names&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Old: &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;strike&gt;package:web_components/web_components.dart&lt;/strike&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
New: &lt;span style="font-family: Courier New, Courier, monospace;"&gt;package:web_ui/web_ui.dart&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Your pubspec.yaml now looks like this:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; dependencies:  
  web_ui: any  &lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Simpler two-way data binding for input fields&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Old:&amp;nbsp;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;strike&gt;data-bind="attribute:dartAssignableValue"&lt;/strike&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
New:&amp;nbsp;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;bind-attribute="dartAssignableValue"&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div class="p1"&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; &amp;lt;input type="text" &lt;b&gt;bind-value="superlative"&lt;/b&gt; placeholder="Enter superlative"&amp;gt;  &lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Simpler declarative event handlers&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Old:&amp;nbsp;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;strike&gt;data-action="click:handleClick"&lt;/strike&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
New:&amp;nbsp;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;on-click="handleClick()"&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Notice how the &lt;i&gt;on-action&lt;/i&gt; form declares an expression (complete with parentheses). You can pass the event to the handler by using &lt;span style="font-family: Courier New, Courier, monospace;"&gt;handleClick($event)&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; &amp;lt;select name="language" &lt;b&gt;on-change="chooseExample($event)"&lt;/b&gt;&amp;gt;  
  &amp;lt;option value=""&amp;gt;-- Choose one --&amp;lt;/option&amp;gt;  
  &amp;lt;option value="js"&amp;gt;JavaScript&amp;lt;/option&amp;gt;  
  &amp;lt;option value="java"&amp;gt;Java&amp;lt;/option&amp;gt;  
 &amp;lt;/select&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Simpler conditional templates&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Old: &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;strike&gt;&amp;lt;template instantiate="if securityClearance == 'top'"&amp;gt;&lt;/strike&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
New: &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;lt;template if="securityClearance == 'top'"&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; &amp;lt;template &lt;b&gt;if="langChoice != null &amp;amp;&amp;amp; !langChoice.isEmpty"&lt;/b&gt;&amp;gt;  
  &amp;lt;div&amp;gt;  
   &amp;lt;h3&amp;gt;{{ langChoice }}&amp;lt;/h3&amp;gt;  
   &amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;{{ example }}&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;  
  &amp;lt;/div&amp;gt;  
 &amp;lt;/template&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Template tag no longer required&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Option A: &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;lt;template if="securityClearance == 'top'"&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Option B: &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;lt;div template if="securityClearance == 'top'"&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; &amp;lt;div &lt;b&gt;template if="langChoice != null &amp;amp;&amp;amp; !langChoice.isEmpty"&lt;/b&gt;&amp;gt;  
  &amp;lt;h3&amp;gt;{{ langChoice }}&amp;lt;/h3&amp;gt;  
  &amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;{{ example }}&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;  
 &amp;lt;/div&amp;gt;  &lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Summary&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The Dart Web Components package is now the Dart Web UI package. The name was changed to better reflect the breadth of features available, including polyfills for Web Components, dynamic templates, and live data binding. Recent feedback has helped to simplify some of the syntax around event handlers, conditional templates, and more.&lt;br /&gt;
&lt;br /&gt;
You can discuss Dart Web UI at &lt;a href="https://groups.google.com/a/dartlang.org/forum/?fromgroups#!forum/web-ui"&gt;web-ui@dartlang.org mailing list&lt;/a&gt;, or ask questions on &lt;a href="http://stackoverflow.com/tags/dart"&gt;Stack Overflow&lt;/a&gt;. You can follow the open source &lt;a href="https://github.com/dart-lang/web-ui"&gt;Dart Web UI project on Github&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: xx-small;"&gt;(Picture courtesy of&amp;nbsp;&lt;a href="http://www.flickr.com/photos/foxypar4/2124673642/"&gt;http://www.flickr.com/photos/foxypar4/2124673642/&lt;/a&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/1fzA8aGWXzA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/8041648823099038240/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=8041648823099038240&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/8041648823099038240?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/8041648823099038240?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/1fzA8aGWXzA/4-new-features-from-dart-web-ui.html" title="4 New Simplifications from Dart Web UI" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-ke2ObxG1ojs/UMWgaYp_VII/AAAAAAAAOJE/yZx-FwiX_p4/s72-c/2124673642_115fb71c69.jpg" height="72" width="72" /><thr:total>2</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2012/12/4-new-features-from-dart-web-ui.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcASXc9eCp7ImA9WhNWEU4.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-8800379240337341005</id><published>2012-11-25T22:16:00.002-08:00</published><updated>2012-12-10T01:00:48.960-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-10T01:00:48.960-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="webcomponents" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>Your First Loop with Dart Web Components</title><content type="html">In which the trusty and powerful &lt;i&gt;loop&lt;/i&gt; is given its time to shine in Dart Web UI. Thus far, we've looked at data binding, conditionals, and even custom components with Dart Web UI. But you can't get very far without needing to iterate through a collection and render a template for each element. Not to worry! In this post, I'll show you how to bind a collection to a template in Dart Web UI.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-vMufjzbtR5U/ULMEUXcNFqI/AAAAAAAAN_I/MeRpiUhBVSg/s1600/3196346379_90426b540d.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Many loops.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;b&gt;Prerequisites&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
You may want to read &lt;a href="http://blog.sethladd.com/2012/11/your-first-model-driven-view-with-dart.html"&gt;Your First Model Driven View with Dart&lt;/a&gt;, which contains more information on getting started and configure the necessary tools. This post assumes you've read my previous posts on Web Components and Dart.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Overview&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You can render a &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;lt;template&amp;gt;&lt;/span&gt; tag for each item in a collection. Whenever the collection is modified, the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;lt;template&amp;gt;&lt;/span&gt; tag is reapplied for every item in the collection (note: we think this will be optimized in future versions of Dart Web UI).&lt;br /&gt;
&lt;br /&gt;
Keeping with the style of Web Components, this iteration is declarative. To bind a collection to a &amp;lt;template&amp;gt;, you can use the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;iterate&lt;/span&gt; attribute. Here is an example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt;    &amp;lt;template &lt;b&gt;iterate&lt;/b&gt;="fav in userFavorites"&amp;gt;  
     &amp;lt;li&amp;gt;&amp;lt;span&amp;gt;{{ fav }}&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;  
    &amp;lt;/template&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
For every item in &lt;span style="font-family: Courier New, Courier, monospace;"&gt;userFavorites&lt;/span&gt;, a new &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;lt;li&amp;gt;&lt;/span&gt; tag will be created.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Example&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This example displays a list of language features found in Dart, each with a checkbox. The user can select their favorite language features, which will be printed out in a second, sorted list. This example shows off templates, data binding, event handling, and iteration.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The Dart Code&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Here is the Dart code, which sets up the list of language features (the features variable), the collection of favorite features chosen by the user (the userFavorites variable), and the event handler when a user chooses a feature (the addToFavorites function).&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; import 'dart:html';  
   
 List&amp;lt;String&amp;gt; features = const &amp;lt;String&amp;gt;['lexical scope',  
                     'closures',  
                     'getters and setters',  
                     'isolates',  
                     'top-level functions',  
                     'optional static types',  
                     'one-line functions',  
                     'familiar syntax',  
                     'map and list literals',  
                     'generics'];  
   
 // TODO try a Set when it can be watched  
 List&amp;lt;String&amp;gt; userFavorites = new List&amp;lt;String&amp;gt;();  
   
 addToFavorites(Event e) {  
  InputElement checkbox = e.target;  
  var fav = checkbox.value;  
    
  if (checkbox.checked) {  
   userFavorites.add(fav);  
  } else if (!checkbox.checked) {  
   var index = userFavorites.indexOf(fav);  
   userFavorites.removeAt(index);  
  }  
    
  userFavorites.sort();  
 }  
   
 main() { }  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;b&gt;The HTML code&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Here is the HTML code with the Dart Web Components declarations.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt;   &amp;lt;ul&amp;gt;  
    &amp;lt;template &lt;b&gt;iterate&lt;/b&gt;="feature in features"&amp;gt;  
     &amp;lt;li&amp;gt;  
      &amp;lt;label&amp;gt;  
       &amp;lt;input type="checkbox" value="{{ feature }}"  
           &lt;b&gt;on-click="addToFavorites($event)"&lt;/b&gt;&amp;gt;  
       &amp;lt;span&amp;gt;&lt;b&gt;{{ feature }}&lt;/b&gt;&amp;lt;/span&amp;gt;  
      &amp;lt;/label&amp;gt;  
     &amp;lt;/li&amp;gt;  
    &amp;lt;/template&amp;gt;  
   &amp;lt;/ul&amp;gt;  
     
   &amp;lt;h3&amp;gt;Your favorite features&amp;lt;/h3&amp;gt;  
     
   &amp;lt;ul&amp;gt;  
    &amp;lt;template &lt;b&gt;iterate&lt;/b&gt;="fav in userFavorites"&amp;gt;  
     &amp;lt;li&amp;gt;&amp;lt;span&amp;gt;&lt;b&gt;{{ fav }}&lt;/b&gt;&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;  
    &amp;lt;/template&amp;gt;  
   &amp;lt;/ul&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;b&gt;Working demo&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Here is an embedded live demo for you to try. It has been compiled to vanilla JavaScript and HTML so that it works in all modern browsers.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe height="400" src="http://sethladd.github.com/dart-web-components-tests/web/out/Iterate.html" width="600"&gt;&lt;/iframe&gt;

&lt;br /&gt;
&lt;br /&gt;
(If you can't see the above embedded demo, you can try &lt;a href="http://sethladd.github.com/dart-web-components-tests/web/out/Iterate.html" target="_blank"&gt;this direct link&lt;/a&gt;.)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Summary&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You can declaratively iterate through collections with the &amp;lt;template&amp;gt; tag in Dart Web Components. The collection is bound to the template, which updates any time the collection is updated.&lt;br /&gt;
&lt;br /&gt;
You can see the source for this and more &lt;a href="https://github.com/sethladd/dart-web-components-tests"&gt;Dart Web Components samples on Github&lt;/a&gt;. Meanwhile, &lt;a href="http://www.dartlang.org/articles/dart-web-components/"&gt;read more about Dart Web Components&lt;/a&gt;. Have fun!&lt;br /&gt;
&lt;span style="font-size: xx-small;"&gt;(Image courtesy of&amp;nbsp;&lt;a href="http://www.flickr.com/photos/jenny-pics/3196346379/"&gt;http://www.flickr.com/photos/jenny-pics/3196346379/&lt;/a&gt;)&lt;/span&gt;&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/0TGGhed1QZw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/8800379240337341005/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=8800379240337341005&amp;isPopup=true" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/8800379240337341005?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/8800379240337341005?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/0TGGhed1QZw/your-first-loop-with-dart-web-components.html" title="Your First Loop with Dart Web Components" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-vMufjzbtR5U/ULMEUXcNFqI/AAAAAAAAN_I/MeRpiUhBVSg/s72-c/3196346379_90426b540d.jpg" height="72" width="72" /><thr:total>1</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2012/11/your-first-loop-with-dart-web-components.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04MQng6fSp7ImA9WhNWEU8.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-8878818683153584264</id><published>2012-11-21T22:48:00.002-08:00</published><updated>2012-12-10T00:59:43.615-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-10T00:59:43.615-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="webcomponents" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>Your First Conditional Template with Dart Web Components</title><content type="html">As if data binding and custom elements with Dart Web UI isn't enough, you can also conditionally render blocks of elements via simple declarative attributes! The conditionals are "live" and are re-evaluated when data changes, keeping your page dynamic and up-to-date.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img border="0" src="http://3.bp.blogspot.com/-CYbV0s8EZAI/UK3Bck1O9BI/AAAAAAAAN6s/ln0G1wXDePA/s1600/4981201339_404f068704.jpg" /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
(You may want to read &lt;a href="http://blog.sethladd.com/2012/11/your-first-model-driven-view-with-dart.html"&gt;Your First Model Driven View with Dart&lt;/a&gt;, which contains more information on getting started and configure the necessary tools. This post assumes you've read my previous posts on Web Components and Dart.)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Conditionals templates&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
With Dart Web UI, you can conditionally display elements. For example, you can declaratively say "If the checkbox is checked, then display the thank you notice." Here's an example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; &lt;b&gt;&amp;lt;template if="acceptLicense"&amp;gt;&lt;/b&gt;  
  &amp;lt;h2&amp;gt;Thanks!&amp;lt;/h2&amp;gt;  
  &amp;lt;p&amp;gt;We'll send you an activation key to your email.&amp;lt;/p&amp;gt;  
 &lt;b&gt;&amp;lt;/template&amp;gt;&lt;/b&gt;  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
In the above example, the &amp;lt;h2&amp;gt; and &amp;lt;p&amp;gt; will only be added to the DOM if the acceptLicense variable becomes true. If acceptLicense becomes false, the template contents are removed from the DOM.&lt;br /&gt;
&lt;br /&gt;
A &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;lt;template&amp;gt;&lt;/span&gt; is an inert set of elements, which is parsed but not activated and not immediately added to the DOM. To render the elements in a template, the conditional in the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;if&lt;/span&gt; must become true. You can use any Dart code that results in a boolean for the conditional.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Full example&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Here is a complete Dart Web UI page with a conditional template. The below example also demonstrates data binding with a checkbox.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; &amp;lt;!DOCTYPE html&amp;gt;  
   
 &amp;lt;html&amp;gt;  
  &amp;lt;head&amp;gt;  
   &amp;lt;meta charset="utf-8"&amp;gt;  
   &amp;lt;title&amp;gt;Simple Conditional&amp;lt;/title&amp;gt;  
   &amp;lt;link rel="stylesheet" href="App.css"&amp;gt;  
  &amp;lt;/head&amp;gt;  
  &amp;lt;body&amp;gt;  
   &amp;lt;h1&amp;gt;Simple Conditional with Data Binding&amp;lt;/h1&amp;gt;  
     
   &amp;lt;p&amp;gt;  
    &amp;lt;label&amp;gt;  
     &amp;lt;input type="checkbox" id="accept-license" bind-checked="acceptLicense"&amp;gt;  
     I accept the license  
    &amp;lt;/label&amp;gt;  
   &amp;lt;/p&amp;gt;  
     
   &amp;lt;template if="acceptLicense"&amp;gt;  
    &amp;lt;h2&amp;gt;Thanks!&amp;lt;/h2&amp;gt;  
    &amp;lt;p&amp;gt;We'll send the activation key to your email.&amp;lt;/p&amp;gt;  
   &amp;lt;/template&amp;gt;  
   
   &amp;lt;script type="application/dart"&amp;gt;  
    bool acceptLicense = false;  
    main() { }  
   &amp;lt;/script&amp;gt;  
   &amp;lt;script src="https://dart.googlecode.com/svn/branches/bleeding_edge/dart/client/dart.js"&amp;gt;&amp;lt;/script&amp;gt;  
  &amp;lt;/body&amp;gt;  
 &amp;lt;/html&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
To compile the above file into vanilla JavaScript and HTML, learn more about the &lt;a href="http://www.dartlang.org/articles/dart-web-components/tools.html"&gt;Dart Web Components tools&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Working example&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Enjoy this fully working example, compiled to JavaScript.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe height="200" src="http://sethladd.github.com/dart-web-components-tests/web/out/simple_conditional.html" width="600"&gt;&lt;/iframe&gt;

&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Summary&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Use conditional templates with data binding to control the display of blocks of elements. Use a &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;lt;template if="some_boolean_expression"&amp;gt;&lt;/span&gt; to conditionally render elements to a page. The conditional template is "live" and is re-evaluated when data changes.&lt;br /&gt;
&lt;br /&gt;
You can see the source for this and more &lt;a href="https://github.com/sethladd/dart-web-components-tests"&gt;Dart Web Components samples on Github&lt;/a&gt;. Meanwhile, &lt;a href="http://www.dartlang.org/articles/dart-web-components/"&gt;read more about Dart Web Components&lt;/a&gt;. Have fun!&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: xx-small;"&gt;(image courtesy of&amp;nbsp;&lt;a href="http://www.flickr.com/photos/84987970@N00/4981201339/"&gt;http://www.flickr.com/photos/84987970@N00/4981201339/&lt;/a&gt;)&lt;/span&gt;&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/s0ZXVD1O-1g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/8878818683153584264/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=8878818683153584264&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/8878818683153584264?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/8878818683153584264?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/s0ZXVD1O-1g/your-first-conditional-template-with.html" title="Your First Conditional Template with Dart Web Components" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-CYbV0s8EZAI/UK3Bck1O9BI/AAAAAAAAN6s/ln0G1wXDePA/s72-c/4981201339_404f068704.jpg" height="72" width="72" /><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2012/11/your-first-conditional-template-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08HSH49fCp7ImA9WhNWEU8.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-7163410371085309283</id><published>2012-11-17T23:21:00.003-08:00</published><updated>2012-12-10T00:57:19.064-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-10T00:57:19.064-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="webcomponents" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>Your First Input Field Binding with Web Components and Dart</title><content type="html">Updating a &lt;i&gt;web page&lt;/i&gt; when the data changes is cool. Updating the &lt;i&gt;data&lt;/i&gt; when the web page changes is even cooler. Read on to learn how to create a live data binding between form fields, data, and your web page with Web Components, Model Driven Views, and &lt;a href="http://www.dartlang.org/"&gt;Dart&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-2GtuHxq5b6M/UKh6K_A3atI/AAAAAAAAN6Q/XQUMYoEhUno/s1600/3098090721_610443c862.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-2GtuHxq5b6M/UKh6K_A3atI/AAAAAAAAN6Q/XQUMYoEhUno/s320/3098090721_610443c862.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Artful binding.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
(You may want to read&amp;nbsp;&lt;a href="http://blog.sethladd.com/2012/11/your-first-model-driven-view-with-dart.html"&gt;Your First Model Driven View with Dart&lt;/a&gt;, which contains more information on getting started. This post assumes you've read my previous posts on Web Components and Dart.)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;What do I mean, binding?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In the context of user interfaces, data binding is the technique of keeping both data and the view in sync. If the data changes, update the view. If the view changes, update the data. It's the later scenario (view changing the data) that I discuss in this post.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The HTML&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
HTML views can update data via input fields.&amp;nbsp;Input fields can be bound to data, both displaying the data and updating the data. Use the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;data-bind&lt;/span&gt; attribute on input fields such as text, textarea, and select.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; &amp;lt;p&amp;gt;MDV is {{ superlative }}&amp;lt;/p&amp;gt;  
 &amp;lt;div&amp;gt;  
  &amp;lt;input type="text" &lt;b&gt;bind-value="superlative"&lt;/b&gt; placeholder="Enter superlative"&amp;gt;  
 &amp;lt;/div&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
The above code sample shows two data bindings. The first, &lt;span style="font-family: Courier New, Courier, monospace;"&gt;{{ superlative }}&lt;/span&gt;, we saw in my &lt;a href="http://blog.sethladd.com/2012/11/your-first-model-driven-view-with-dart.html"&gt;previous post&lt;/a&gt;. The second, data-bind, is how you declare a binding for an input field.&lt;br /&gt;
&lt;br /&gt;
Specifically, &lt;span style="font-family: Courier New, Courier, monospace;"&gt;bind-value="superlative"&lt;/span&gt; is saying "bind the superlative variable found in Dart code to the value attribute of this input field". The &lt;a href="http://www.dartlang.org/articles/dart-web-components/"&gt;Dart Web Components document&lt;/a&gt; calls this "two-way binding", because the input field itself is bound in two ways: reading and writing the variable.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The Dart&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In this simple example, the Dart code only declares the variable and defines the main method.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; String superlative = '';  
 main() { }  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
One of the main benefits of Web Components is that everything is very declarative, so the need for glue code or explicit event handlers is diminished.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The results&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Best to show this off live, so you can see the live data binding.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe height="200" src="http://sethladd.github.com/dart-web-components-tests/web/out/FormBinding.html" width="500"&gt;&lt;/iframe&gt;

&lt;br /&gt;
Notice how the display is updated as the user types in the input field. To make this happen, almost no code was created, and everything was simply declared in the HTML. Awesome!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Summary&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Use the data-bind attribute on input fields to declare live "two-way" data binding. When the variable's value is changed, the input field changes. When the user updates the input field, the variable's value changes.&lt;br /&gt;
&lt;br /&gt;
Read the &lt;a href="http://www.dartlang.org/articles/dart-web-components/"&gt;Dart Web Components documentation&lt;/a&gt; or check out my other &lt;a href="http://blog.sethladd.com/search/label/webcomponents"&gt;blog posts on Dart Web Components&lt;/a&gt;. The &lt;a href="https://github.com/sethladd/dart-web-components-tests"&gt;code from this post&lt;/a&gt;, and other examples of Dart Web Components, is available on &lt;a href="https://github.com/sethladd/dart-web-components-tests"&gt;Github&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Thanks!&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;(Binding image courtesy of&amp;nbsp;&lt;a href="http://www.flickr.com/photos/ruthbleakley/3098090721/"&gt;http://www.flickr.com/photos/ruthbleakley/3098090721/&lt;/a&gt;)&lt;/span&gt;&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/VIiDe0QyNk4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/7163410371085309283/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=7163410371085309283&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/7163410371085309283?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/7163410371085309283?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/VIiDe0QyNk4/your-first-input-field-binding-with-web.html" title="Your First Input Field Binding with Web Components and Dart" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-2GtuHxq5b6M/UKh6K_A3atI/AAAAAAAAN6Q/XQUMYoEhUno/s72-c/3098090721_610443c862.jpg" height="72" width="72" /><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2012/11/your-first-input-field-binding-with-web.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcEQHsycCp7ImA9WhNRGE0.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-3379190367155960363</id><published>2012-11-13T01:46:00.001-08:00</published><updated>2012-11-13T01:46:41.598-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-11-13T01:46:41.598-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><category scheme="http://www.blogger.com/atom/ns#" term="book" /><title>Dart Up &amp; Running book now available</title><content type="html">&lt;i&gt;Achievement unlocked: Published an O'Reilly book!&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://shop.oreilly.com/product/0636920025719.do"&gt;Dart Up &amp;amp; Running&lt;/a&gt;, a quick and easy guide for learning &lt;a href="http://www.dartlang.org/"&gt;Dart&lt;/a&gt;, is now ready for shipping. A huge thanks to my co-author &lt;a href="https://plus.google.com/105904968710974272643/posts"&gt;Kathy Walrath&lt;/a&gt; and our many reviewers. We hope you enjoy reading this book and using Dart to build modern web apps!&lt;br /&gt;
&lt;br /&gt;
Buy Dart Up &amp;amp; Running printed and e-books at &lt;a href="http://shop.oreilly.com/product/0636920025719.do"&gt;O'Reilly&lt;/a&gt; or &lt;a href="http://www.amazon.com/Dart-Up-Running-Kathy-Walrath/dp/1449330894/"&gt;Amazon&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-Js3S2QW8nMs/UKIWJmGMtvI/AAAAAAAANuk/De_Q2PDRLGY/s1600/dart+up+and+running.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://2.bp.blogspot.com/-Js3S2QW8nMs/UKIWJmGMtvI/AAAAAAAANuk/De_Q2PDRLGY/s400/dart+up+and+running.jpg" width="304" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
In the book, you'll learn about the Dart language, libraries, and tools such as Dart Editor and our pub package manager. There's even an application walk-through, looking at a client-side and server-side Dart app.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
As you learn Dart, be sure to join our &lt;a href="http://www.dartlang.org/mailing-list"&gt;mailing list&lt;/a&gt; and ask questions on &lt;a href="http://stackoverflow.com/tags/dart"&gt;Stack Overflow&lt;/a&gt;.&lt;/div&gt;
&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/3DTIKGDapdA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/3379190367155960363/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=3379190367155960363&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/3379190367155960363?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/3379190367155960363?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/3DTIKGDapdA/dart-up-running-book-now-available.html" title="Dart Up &amp; Running book now available" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-Js3S2QW8nMs/UKIWJmGMtvI/AAAAAAAANuk/De_Q2PDRLGY/s72-c/dart+up+and+running.jpg" height="72" width="72" /><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2012/11/dart-up-running-book-now-available.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YHRHwzfSp7ImA9WhNWEU8.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-3897382407700557980</id><published>2012-11-12T03:38:00.003-08:00</published><updated>2012-12-10T00:45:35.285-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-10T00:45:35.285-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="webcomponents" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><category scheme="http://www.blogger.com/atom/ns#" term="#dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="#dart" /><title>Your First Model Driven View with Dart</title><content type="html">Packed inside the &lt;a href="https://github.com/dart-lang/web-ui"&gt;Dart Web UI&lt;/a&gt; project is inspired by&amp;nbsp;&lt;a href="http://code.google.com/p/mdv/"&gt;Model Driven Views&lt;/a&gt; (also known as MDV). While Web Components provides encapsulation and reusability, it doesn't say much about linking your data and models with your views. &lt;b&gt;MDV is a set of techniques to help you bind your data to your views&lt;/b&gt;, and just like Web Components, &lt;b&gt;you can use Dart with MDV-esque behavior today&lt;/b&gt;.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
Everything you are about to read works across modern browsers, because Dart compiles to JavaScript.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-wwBoyZyi0hc/UKDZ9r4e9DI/AAAAAAAANtg/sRZbPCX1gYI/s1600/3017776337768526_comb_binding.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-wwBoyZyi0hc/UKDZ9r4e9DI/AAAAAAAANtg/sRZbPCX1gYI/s1600/3017776337768526_comb_binding.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The binding.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Intro&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The MDV behavior of Dart Web UI (hereafter referred to as Web UI) helps you bind your data and models to the view in a declarative manner. Binding usually means "when the data changes in one location, change it in another." Typically, web frameworks can wire together the necessary callbacks to keep the view (any text or input fields) in sync with the models (the Dart objects that contain the state of the application).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Setup&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both;"&gt;
Remember, you'll need a pubspec.yaml that included the web_components package:&lt;/div&gt;
&lt;div class="separator" style="clear: both;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; name: App  
 description: A sample application  
 dependencies:  
  web_ui: any  
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
If you're new to Dart Web Components, you might want to read my&amp;nbsp;&lt;a href="http://blog.sethladd.com/2012/11/your-first-web-component-with-dart.html"&gt;Your First Web Component with Dart&lt;/a&gt;&amp;nbsp;post, or the&amp;nbsp;&lt;a href="http://www.dartlang.org/articles/dart-web-components/"&gt;Dart Web Components article&lt;/a&gt;. Just like Dart Web Components, for MDV to work you need to get the web_components package, which contains the dwc compiler. The compiler is what converts the MVC and WC code into vanilla Dart and HTML. You can use dart2js to convert the Dart into JavaScript and run these samples across all major browsers.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Sample code&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Let's look at a simple example that takes some data from Dart and displays it on a web page. We also add a button that, when clicked, updates the data which in turn updates the data on the page. Binding in action!&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Here is the HTML:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; &amp;lt;body&amp;gt;  
  &amp;lt;h1&amp;gt;Hello MDV&amp;lt;/h1&amp;gt;  
  &amp;lt;p&amp;gt;MDV is {{ superlative }}&amp;lt;/p&amp;gt;  
  &amp;lt;button id="change-it" on-click="changeIt()"&amp;gt;Change&amp;lt;/button&amp;gt;  
  &amp;lt;script type="application/dart" src="HelloWorld.dart"&amp;gt;&amp;lt;/script&amp;gt;  
  &amp;lt;script src="dart.js"&amp;gt;&amp;lt;/script&amp;gt;  
 &amp;lt;/body&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div class="p1"&gt;
Note the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;b&gt;{{ superlative }}&lt;/b&gt;&lt;/span&gt; is a placeholder for data, to be populated by the MDV code. The name superlative is the name of a variable in Dart code.&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
The &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;b&gt;on-click="changeIt()"&lt;/b&gt;&lt;/span&gt; is an attribute that tells MDV to run the &lt;i&gt;changeIt&lt;/i&gt; method whenever the button is clicked. The name changeIt is the name of a top-level function in Dart code.&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
Here is the Dart code:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; import 'dart:math';  
 String superlative;  
 List&amp;lt;String&amp;gt; alternatives = const ['wicked cool', 'sweet', 'fantastic'];  
 Random random;  
 main() {  
  superlative = 'awesome';  
  random = new Random();
 }  
 changeIt() =&amp;gt; superlative = alternatives[random.nextInt(alternatives.length)];  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
Note the top-level variable named &lt;span style="font-family: Courier New, Courier, monospace;"&gt;superlative&lt;/span&gt;, which is initially set to 'awesome' in main. When the page is first displayed, you will see:&lt;br /&gt;
&lt;br /&gt;
&lt;iframe height="150" src="http://sethladd.github.com/dart-web-components-tests/web/out/HelloWorld.html" width="600"&gt;&lt;/iframe&gt;

&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
(If you can't see the embedded demo above, you can &lt;a href="http://sethladd.github.com/dart-web-components-tests/web/out/HelloWorld.html" target="_blank"&gt;try the live demo&lt;/a&gt;.)&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
How cool is that?! Here we see simple data binding in action.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
When the button is clicked, the changeIt function is run. A random alternative is chosen and assigned to the variable superlative. After the button is clicked, the view is updated.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
The MDV code takes care of all the bindings and updating. &lt;b&gt;The Dart code doesn't contain any code or logic to update the view when a value changed.&lt;/b&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
There's a lot more to Dart's support for MDV, which I'll cover in future blog posts. You can see this and more code at&amp;nbsp;&lt;a href="https://github.com/sethladd/dart-web-components-tests"&gt;https://github.com/sethladd/dart-web-components-tests&lt;/a&gt; &amp;nbsp;The work on Dart Web Components and MDV is just beginning, so please try it out and send feedback. Thanks!&lt;/div&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/CZqxAdE3Umw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/3897382407700557980/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=3897382407700557980&amp;isPopup=true" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/3897382407700557980?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/3897382407700557980?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/CZqxAdE3Umw/your-first-model-driven-view-with-dart.html" title="Your First Model Driven View with Dart" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-wwBoyZyi0hc/UKDZ9r4e9DI/AAAAAAAANtg/sRZbPCX1gYI/s72-c/3017776337768526_comb_binding.jpg" height="72" width="72" /><thr:total>1</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2012/11/your-first-model-driven-view-with-dart.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMER3o7eyp7ImA9WhNRF0w.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-4084000894276724071</id><published>2012-11-12T03:06:00.001-08:00</published><updated>2012-11-12T03:06:46.403-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-11-12T03:06:46.403-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><category scheme="http://www.blogger.com/atom/ns#" term="#dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="#dart" /><title>Dart Up and Running Webcast from O'Reilly</title><content type="html">O'Reilly, our publisher for the new &lt;a href="http://shop.oreilly.com/product/0636920025719.do"&gt;Dart Up &amp;amp; Running&lt;/a&gt; book by Kathy Walrath and yours truly, ran a webcast to help promote &lt;a href="http://www.dartlang.org/"&gt;Dart&lt;/a&gt; and the book.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="allowfullscreen" frameborder="0" height="360" src="http://www.youtube.com/embed/4o3s0_ISLFM" width="640"&gt;&lt;/iframe&gt;

&lt;br /&gt;
(If you can't see the embed, you can &lt;a href="http://www.youtube.com/watch?v=4o3s0_ISLFM"&gt;watch the video directly on YouTube&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
This is the first time I used a Hangout for an entire webcast, and I admit the fonts are hard to read in this recording. Good lesson learned for next time!&lt;br /&gt;
&lt;br /&gt;
Thanks to everyone who watched, and thanks to Kathy for monitoring the back channel and funneling questions from our viewers.&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/Vqrw3LxtubA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/4084000894276724071/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=4084000894276724071&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/4084000894276724071?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/4084000894276724071?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/Vqrw3LxtubA/dart-up-and-running-webcast-from-oreilly.html" title="Dart Up and Running Webcast from O'Reilly" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/4o3s0_ISLFM/default.jpg" height="72" width="72" /><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2012/11/dart-up-and-running-webcast-from-oreilly.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQER386fyp7ImA9WhNRFEk.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-6122918077753848263</id><published>2012-11-08T23:48:00.000-08:00</published><updated>2012-11-08T23:48:26.117-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-11-08T23:48:26.117-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><title>Dart is Breaking Open, Interview with Marakana</title><content type="html">I had a fun time at Marakana as a guest on their new show "Breaking Open". We talked about &lt;a href="http://www.dartlang.org/"&gt;Dart&lt;/a&gt; and scaling web development.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;object width="320" height="266" class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://1.gvt0.com/vi/pqbAAZF8kP0/0.jpg"&gt;&lt;param name="movie" value="http://www.youtube.com/v/pqbAAZF8kP0&amp;fs=1&amp;source=uds" /&gt;&lt;param name="bgcolor" value="#FFFFFF" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;embed width="320" height="266"  src="http://www.youtube.com/v/pqbAAZF8kP0&amp;fs=1&amp;source=uds" type="application/x-shockwave-flash" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;
&lt;br /&gt;
"We're building Dart to help web developers start small, and grow over time to classes, and then libraries, and then tens of developers, and then hundreds of developers."&lt;br /&gt;
&lt;br /&gt;
Thanks for watching!&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/kEF5D-GN0bc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/6122918077753848263/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=6122918077753848263&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/6122918077753848263?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/6122918077753848263?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/kEF5D-GN0bc/dart-is-breaking-open-interview-with.html" title="Dart is Breaking Open, Interview with Marakana" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><thr:total>0</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2012/11/dart-is-breaking-open-interview-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUAHRHY5eCp7ImA9WhNWEU8.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-1986310583688172925</id><published>2012-11-06T00:05:00.001-08:00</published><updated>2012-12-10T00:22:15.820-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-10T00:22:15.820-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="webcomponents" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><category scheme="http://www.blogger.com/atom/ns#" term="#dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="#dart" /><title>Your First Web Component with Dart</title><content type="html">With all the power we have from HTML5 and the modern web platform, you can't easily do simple things like extend &amp;lt;button&amp;gt;. Luckily, this is changing and the web platform is undergoing a declarative&amp;nbsp;renaissance.&amp;nbsp; Thanks to the hard work of many groups and individuals across different browser vendors and spec committees, Web Components are emerging as the way to bring structure and encapsulation to modern web developers. The best news yet: you don't need to wait years for these new standards to be implemented, you can use&amp;nbsp;&lt;a href="http://www.dartlang.org/"&gt;Dart&lt;/a&gt;&amp;nbsp;to build Web Components today.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-KKRYizzEK5I/UJi9IXnM7BI/AAAAAAAANdI/RwInfXj3Tvs/s1600/Screen+Shot+2012-11-05+at+11.32.34+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="224" src="http://3.bp.blogspot.com/-KKRYizzEK5I/UJi9IXnM7BI/AAAAAAAANdI/RwInfXj3Tvs/s640/Screen+Shot+2012-11-05+at+11.32.34+PM.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Web Component basics&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The component model for the web, aka&amp;nbsp;&lt;a href="http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html"&gt;Web Components&lt;/a&gt;, is a collection of specifications that allow developers to build reusable, encapsulated, and declarative widgets.&lt;br /&gt;
&lt;br /&gt;
When people say "Web Components" they generally mean these four ideas:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;templates&lt;/i&gt;, which define chunks of markup that are inert but can be activated for use later&lt;/li&gt;
&lt;li&gt;&lt;i&gt;decorators&lt;/i&gt;, which apply templates to let CSS affect rich visual and behavioral changes to documents&lt;/li&gt;
&lt;li&gt;&lt;i&gt;custom elements&lt;/i&gt;, which let authors define their own elements, including new presentation and API, that can be used in HTML documents&lt;/li&gt;
&lt;li&gt;&lt;i&gt;shadow DOM&lt;/i&gt;&amp;nbsp;which defines how presentation and behavior of decorators and custom elements fit together in the DOM tree&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;b&gt;Custom elements&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I'm most excited by custom elements because they allow me to build, share, and use &amp;lt;x-fancy-button&amp;gt; in my apps.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
A custom element can encapsulate the structure, styles, and behavior of a user-defined tag. The structure, or all the nested divs and spaces, is hidden inside the custom element and not immediately visible to the page's DOM. The CSS styles can be scoped to just this new element, to prevent leaking through to the rest of the document. Custom behavior, via JavaScript or Dart, can be attached to further specialize the API of the element.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Data binding&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Most developers want a way to update the view (aka the HTML page) when the model (aka plain old Dart objects) changes, and visa versa. This technique is called data binding, and most modern MVC-esque frameworks have some support for making this easy.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
While not specifically part of the Web Components page 'o tricks,&amp;nbsp;&lt;i&gt;model driven views&lt;/i&gt;&amp;nbsp;are an important aspect to the emerging modern web app stack. MDV, as it is often called, uses a declarative syntax for one-way and two-way data binding of data and views.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Using Web Components today&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The Dart team has been hard at work building &lt;a href="https://github.com/dart-lang/web-ui"&gt;Web UI in Dart&lt;/a&gt;&amp;nbsp;that builds on top of Web Components, and making them available to modern browsers today. It's easy to write your first component, let me show you how.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
(The following assumes you have &lt;a href="http://www.dartlang.org/editor"&gt;Dart Editor&lt;/a&gt; installed and working. While it's not a requirement, the editor makes things a bit easier thanks to its automated build system.)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;1) Create a new project&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Create a new project in Dart Editor, with both "Generate content for a basic web app" and "Add Pub support" checked.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-0loUo4i0Ph8/UJi64lMK5eI/AAAAAAAANdA/rNAyXtl2RHY/s1600/Screen+Shot+2012-11-05+at+11.22.48+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="188" src="http://3.bp.blogspot.com/-0loUo4i0Ph8/UJi64lMK5eI/AAAAAAAANdA/rNAyXtl2RHY/s400/Screen+Shot+2012-11-05+at+11.22.48+PM.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;2) Add the Web Components package&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Open the pubspec.yaml file and add the dependency to the web_components package:&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; name: App  
 description: A sample application  
   
 dependencies:  
  web_ui: any  
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;3) Install dependencies&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Select the pubspec.yaml file in the editor and go to Tools | Pub Install. Assuming it worked, you will see a new packages folder in your application, with web_components and all of its dependencies.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-vy-mmTSG2jw/UJi9g970SwI/AAAAAAAANdQ/iXIjY7-UlQk/s1600/Screen+Shot+2012-11-05+at+11.33.53+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-vy-mmTSG2jw/UJi9g970SwI/AAAAAAAANdQ/iXIjY7-UlQk/s320/Screen+Shot+2012-11-05+at+11.33.53+PM.png" width="293" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;4) Add the build script&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Web Components need to be compiled into vanilla Dart (and then, JavaScript) and HTML. To make this easy, the editor can run a build script whenever a file is changed. Don't worry, it's very fast.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Add this file as &lt;span style="font-family: Courier New, Courier, monospace;"&gt;build.dart&lt;/span&gt; in the root of your application (parallel to web/ and packages/):&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; import 'package:web_components/component_build.dart';  
 import 'dart:io';  
   
 void main() {  
  build(new Options().arguments, ['web/App.html']);  
 }  &lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;5) Add the custom component&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This example uses a custom component for a clickable button and its output. Not exactly the most exciting thing in the world, but it's small and self contained.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Create a &lt;span style="font-family: Courier New, Courier, monospace;"&gt;click.html&lt;/span&gt; file inside the web/ directory and add this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; &amp;lt;html&amp;gt;&amp;lt;body&amp;gt;  
  &amp;lt;element name="x-click-counter" constructor="CounterComponent" extends="div"&amp;gt;  
   &amp;lt;template&amp;gt;  
    &amp;lt;div&amp;gt;  
     &amp;lt;button on-click="increment()"&amp;gt;Click me&amp;lt;/button&amp;gt;  
     &amp;lt;span&amp;gt;(click count: {{count}})&amp;lt;/span&amp;gt;  
    &amp;lt;/div&amp;gt;  
   &amp;lt;/template&amp;gt;  
   &amp;lt;script type="application/dart"&amp;gt;  
    import 'package:web_ui/web_ui.dart';  
   
    class CounterComponent extends WebComponent {  
     int count = 0;  
     void increment() { count++; }  
    }  
   &amp;lt;/script&amp;gt;  
  &amp;lt;/element&amp;gt;  
 &amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The &amp;lt;element&amp;gt; tag defines the new custom element, which in this case extends the &amp;lt;div&amp;gt; element. The structure of this new element is found inside the &amp;lt;template&amp;gt; tag.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
When the &amp;lt;button&amp;gt; is clicked, the &lt;i&gt;increment&lt;/i&gt;&amp;nbsp;method is called on this element. This custom behavior is defined in the Dart code inside of the &amp;lt;script&amp;gt; tag.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The &lt;span style="font-family: Courier New, Courier, monospace;"&gt;{{count}}&lt;/span&gt; syntax is data binding between the element's count field (again, defined in the &amp;lt;script&amp;gt; code) and the DOM output. When the element's count field changes, the DOM is updated.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;6) Clean up the editor's default boilerplate&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Delete the following files from your project, they aren't needed for this example:&lt;/div&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;web/App.dart&lt;/li&gt;
&lt;li&gt;App.html&lt;/li&gt;
&lt;li&gt;App.css&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;b&gt;7) Use the custom element&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Create a web/App.html and use the following code:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; &amp;lt;!DOCTYPE html&amp;gt;  
   
 &amp;lt;html&amp;gt;  
  &amp;lt;head&amp;gt;  
   &amp;lt;meta charset="utf-8"&amp;gt;  
   &amp;lt;title&amp;gt;App&amp;lt;/title&amp;gt;  
   &amp;lt;link rel="components" href="click.html"&amp;gt;  
  &amp;lt;/head&amp;gt;  
  &amp;lt;body&amp;gt;  
   &amp;lt;h1&amp;gt;Web Components FTW!&amp;lt;/h1&amp;gt;  
     
   &amp;lt;x-click-counter&amp;gt;&amp;lt;/x-click-counter&amp;gt;  
     
   &amp;lt;script type="application/dart"&amp;gt;main() {}&amp;lt;/script&amp;gt;  
   &amp;lt;script src="https://dart.googlecode.com/svn/branches/bleeding_edge/dart/client/dart.js"&amp;gt;&amp;lt;/script&amp;gt;  
  &amp;lt;/body&amp;gt;  
 &amp;lt;/html&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Notice how the Web Component itself is included into this document with the &amp;lt;link&amp;gt; tag in the &amp;lt;head&amp;gt;. My favorite part is the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;lt;x-click-counter&amp;gt;&lt;/span&gt; right in the middle of the document.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Note the empty main() function in the &amp;lt;script&amp;gt; tag, which is also required.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;8) Run the app!&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The build script should have generated all the code necessary, but if not you can right click on build.dart and select Run.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
You should see a web/out directory, and inside of that a web/out/App.html.html file. Right click on App.html.html and select "Run in Dartium".&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img border="0" height="120" src="http://2.bp.blogspot.com/-HMNwPY7B_E0/UJjDQWQhJVI/AAAAAAAANdg/7VWfkbT7e4s/s400/Screen+Shot+2012-11-05+at+11.58.45+PM.png" width="400" /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
Here is an embedded demo:&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;iframe height="150" src="http://sethladd.github.com/dart-web-components-tests/web/out/click.html" width="600"&gt;&lt;/iframe&gt;

&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
Click the button, and the click count updates!&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
(If you can't see the embedded demo above, you can &lt;a href="http://sethladd.github.com/dart-web-components-tests/web/out/click.html" target="_blank"&gt;try the live demo&lt;/a&gt;.)&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;9) Run the app in Firefox&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Sure, running Dart code natively on the VM is fun, but running a Dart app with Web Components in other modern browsers is even more fun.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Right click on App.html.html and select "Run as JavaScript". This compiles your app into JavaScript and launches your default browser. You can then copy the URL and paste it into other modern browsers. I tried it in stable Chrome, Firefox, and Safari.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Summary&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
There's so much more to cover, but hopefully you saw that it's easy to build Web Components with Dart and compile down to code that runs across modern browsers.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
You can read more about &lt;a href="http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html"&gt;Web Components&lt;/a&gt;, or more about &lt;a href="http://www.dartlang.org/articles/dart-web-components/"&gt;Dart + Web Components&lt;/a&gt;, or more about &lt;a href="http://www.dartlang.org/articles/dart-web-components/tools.html"&gt;Dart + Web Components + Tools&lt;/a&gt;. You can visit the &lt;a href="https://github.com/dart-lang/web-ui"&gt;open-source Dart Web UI project&lt;/a&gt; and even see &lt;a href="http://dart-lang.github.com/dart-web-components/example/todomvc/index.html"&gt;TodoMVC built with Dart + Web Components&lt;/a&gt;.&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/vthQxS1HCyU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/1986310583688172925/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=1986310583688172925&amp;isPopup=true" title="14 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/1986310583688172925?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/1986310583688172925?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/vthQxS1HCyU/your-first-web-component-with-dart.html" title="Your First Web Component with Dart" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-KKRYizzEK5I/UJi9IXnM7BI/AAAAAAAANdI/RwInfXj3Tvs/s72-c/Screen+Shot+2012-11-05+at+11.32.34+PM.png" height="72" width="72" /><thr:total>14</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2012/11/your-first-web-component-with-dart.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEINSXo8fip7ImA9WhNREUk.&quot;"><id>tag:blogger.com,1999:blog-8601579266012455634.post-1681270405782322521</id><published>2012-11-03T09:50:00.001-07:00</published><updated>2012-11-05T11:09:58.476-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-11-05T11:09:58.476-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="dart" /><category scheme="http://www.blogger.com/atom/ns#" term="#dartlang" /><category scheme="http://www.blogger.com/atom/ns#" term="#dart" /><title>Semantics Matter, 4 Examples in Dart</title><content type="html">We recently re-launched the &lt;a href="http://synonym.dartlang.org/"&gt;Dart Synonym&lt;/a&gt; app, which provides mappings between common Dart/JavaScript/C# patterns, idioms, and snippets. If you know how to build a loop or create a function in JavaScript, this is a great way to learn how to do the same thing in &lt;a href="http://www.dartlang.org/"&gt;Dart&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
A great &lt;a href="https://plus.google.com/u/0/106422711035746240826/posts/fXZpQvpKCmZ"&gt;comment on G+&lt;/a&gt;, in response to the re-launch, was "I think Microsoft may have a better idea with TypeScript, which adds a syntax for declaring variable types that should make JavasScript more robust, but it still runs on top of JavaScript, cross browser."&lt;br /&gt;
&lt;br /&gt;
While the &lt;a href="http://news.dartlang.org/2012/10/the-dart-team-welcomes-typescript.html"&gt;Dart team welcomes TypeScript&lt;/a&gt; to the neighborhood, in the end TypeScript is "just JavaScript". It's great that TypeScript fosters better tooling and bigger web apps, but the same warts of JavaScript are still there with TypeScript. One of the main distinctions between Dart and TypeScript is that Dart cleans up the &lt;i&gt;semantics&lt;/i&gt; and not just the &lt;i&gt;syntax&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Don't get me wrong, syntax is important, and Dart offers familiar and easy to use syntax. Here's an example of assigning a function to a variable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;// Dart. A one-line function assigned to a variable.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;var loudify = (msg) =&amp;gt; msg.toUpperCase();&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
While&amp;nbsp;aesthetics&amp;nbsp;and syntax matter, semantics arguably matter more. Here are four examples of how Dart offers easier to understand semantics.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-jd2dLtLq4SE/UJVQu2VT48I/AAAAAAAANaA/J0PosxbARK4/s1600/4637094831_3e17e85f98_o.jpeg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-jd2dLtLq4SE/UJVQu2VT48I/AAAAAAAANaA/J0PosxbARK4/s320/4637094831_3e17e85f98_o.jpeg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Index out of bounds&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Consider accessing an array index that is out of bounds:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;// Dart or JavaScript&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;var foo = ['a', 'b'];&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;foo[3];&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
In Dart, you'll get a &lt;i&gt;RangeError exception&lt;/i&gt;. No doubts what happened there. :)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Method does not exist&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
What happens when you call a method that doesn't exist on an object?&lt;br /&gt;
&lt;br /&gt;
In Dart, &lt;span style="font-family: Courier New, Courier, monospace;"&gt;noSuchMethod()&lt;/span&gt; is called on your object, which means you have a chance to handle the method call. That kind of dynamism is great for frameworks and scripts.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Is a variable a string?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
How do you tell if a variable is a string?&amp;nbsp;In Dart, you can simply do:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;obj is String&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Closures in a for loop&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
What happens to variables closed around inside a &lt;span style="font-family: Courier New, Courier, monospace;"&gt;for&lt;/span&gt; loop?&amp;nbsp;In Dart, a new &lt;span style="font-family: Courier New, Courier, monospace;"&gt;i&lt;/span&gt; variable is created for each loop iteration. This leads to expected behavior:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;// Dart&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;var callbacks = [];&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;for (var i = 0; i &amp;lt; 2; i++) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&amp;nbsp; callbacks.add(() =&amp;gt; print(i));&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;callbacks[0]() // == 0&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Summary&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Syntax matters, but what the language &lt;i&gt;does&lt;/i&gt; matters more. &lt;a href="http://www.dartlang.org/"&gt;Dart&lt;/a&gt; offers semantics that are more obvious, logical, and straight forward. Above all, all that really matters is that you're building awesome HTML5 apps for the modern web. Language doesn't matter, the web matters.﻿&lt;br /&gt;
&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/sethladd/aGPE/~4/K-3teYZ8OFw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.sethladd.com/feeds/1681270405782322521/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8601579266012455634&amp;postID=1681270405782322521&amp;isPopup=true" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/1681270405782322521?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8601579266012455634/posts/default/1681270405782322521?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/sethladd/aGPE/~3/K-3teYZ8OFw/semantics-matter-4-examples-in-dart.html" title="Semantics Matter, 4 Examples in Dart" /><author><name>Seth Ladd</name><uri>https://plus.google.com/118397406534237711570</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-_3znrz32MsU/AAAAAAAAAAI/AAAAAAAAMT8/rmNCJHfyveQ/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-jd2dLtLq4SE/UJVQu2VT48I/AAAAAAAANaA/J0PosxbARK4/s72-c/4637094831_3e17e85f98_o.jpeg" height="72" width="72" /><thr:total>1</thr:total><gd:extendedProperty name="commentSource" value="1" /><gd:extendedProperty name="commentModerationMode" value="FILTERED_POSTMOD" /><feedburner:origLink>http://blog.sethladd.com/2012/11/semantics-matter-4-examples-in-dart.html</feedburner:origLink></entry></feed>
