<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[@script - Code of Serge]]></title><description><![CDATA[Throw enough spaghetti at the wall, maybe something will stick.]]></description><link>http://codeofserge.com/</link><generator>Ghost 0.5</generator><lastBuildDate>Thu, 10 Sep 2026 22:46:14 GMT</lastBuildDate><atom:link href="http://codeofserge.com/tag/script/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[@script, annotation and angular 1.x]]></title><description><![CDATA[<p><code>Note, this post has been edited on 12/11/2014 and 01/12/2015.  These changes were made to keep the code base changes to handle routing and directives.</code></p>

<p>A previous <a href="http://codeofserge.azurewebsites.net/script-annotation-for-the-win/">post</a> talked about a general idea behind data annotation and the ability to mark up classes. But the example was far from being real world or useful.  Today we are going to explore the way that data annotation can be used to decouple business logic with angular bindings.  We are in search of a simpler solution to ES6 modules or RequireJS and Angular modules.</p>

<p><strong>Module Pattern and Angular</strong></p>

<p>ES6 brings us modules and the "import" keyword for better composition management, which basically means that this code:</p>

<pre><code class="language-javascript">import {ngBase} from './ngBase';  
</code></pre>

<p>transforms into RequireJS code that creates a dependency and on './ngBase</p>

<pre><code class="language-javascript">define(['./ngBase'], function($__0) {  
  "use strict";
  if (!$__0 || !$__0.__esModule)
  $__0 = {default: $__0};
  var ngBase = $__0.ngBase;
});
</code></pre>

<p>Nicely enough, ngBase becomes the variable into which the import is piped, scoped to the wrapper function. So how does this play with something like Angular which has its module system. A quick look online brings about a general consensus that the module pattern is good for business logic, but the angular bootstrapping should take place once the require js modules are loaded.</p>

<ul>
<li><a href="http://www.sitepoint.com/using-requirejs-angularjs-applications/">http://www.sitepoint.com/using-requirejs-angularjs-applications/</a></li>
<li><a href="http://solutionoptimist.com/2013/09/30/requirejs-angularjs-dependency-injection/">http://solutionoptimist.com/2013/09/30/requirejs-angularjs-dependency-injection/</a></li>
<li><a href="http://marcoslin.github.io/angularAMD/#/home">http://marcoslin.github.io/angularAMD/#/home</a></li>
<li><a href="http://stackoverflow.com/questions/12529083/does-it-make-sense-to-use-require-js-with-angular-js">http://stackoverflow.com/questions/12529083/does-it-make-sense-to-use-require-js-with-angular-js</a></li>
</ul>

<p>Each of these post talks about creating non-angular aware modules that are later bootstrapped in another bootstrapping file. In my mind, this is a bit messy.  When anything changes, you must change the bootstrapping file and the implementation file logic. But data annotation solves this problem. We can defer bootstrapping by marking our classes with all required data annotations to complete the late bootstrapping.</p>

<p><strong>Annotate it All</strong></p>

<p>So data annotation lets us create classes that understand their own purpose. Ideally, anything in Angular can be broken down into a class constructor function with annotation that defines the class function.</p>

<p>We annotate the controller/factory/directive name and dependency list into the ngController/ngFactory/ngDirective and ngInject annotation.</p>

<p><strong>Annotation Classes</strong></p>

<p>The magic behind this type of annotation is a collection of annotation classes that can register the class it annotates against an angular module.</p>

<p><a href="https://github.com/SergeiGolos/CodeOfSerge/blob/master/script-annotation-and-angular-1x/src/lib/ngBase.ats">ngBase</a> class is an abstract that all Angular-based annotations derive from. We do have a useful <em>wrap</em> function, which allows us to wrap the Angular array notation for dependency injection. The ngBase class is common ground for all Angular annotations from Angular registering functions (ngController/ngFactory/ngDirective).</p>

<p><a href="https://github.com/SergeiGolos/CodeOfSerge/blob/master/script-annotation-and-angular-1x/src/lib/ngController.ats">ngController</a> class is an actual annotation class. It describes controllers to angular modules. The register function, which is aware of annotation on the class, can work in combination with other annotations like route and inject. The controller annotation simply takes the name.</p>

<pre><code class="language-javascript">@ngController('main')
@ngInject(['$scope', 'data'])
@ngRoute('/Home', { templateUrl : 'home.html' });

export class main {  
  constructor($scope, data) {
    $scope.data = data();
  }
}
</code></pre>

<p><a href="https://github.com/SergeiGolos/CodeOfSerge/blob/master/script-annotation-and-angular-1x/src/lib/ngFactory.ats">ngFactory</a> annotation class for creating factories, the Angular version of a singleton.  Like ngController, it also works in combination with</p>

<pre><code class="language-javascript">@ngFactory('data')

export class data {  
  constructor() {
    return () =&gt; "test";
  }
}
</code></pre>

<p><a href="https://github.com/SergeiGolos/CodeOfSerge/blob/master/script-annotation-and-angular-1x/src/lib/ngDirective.ats">ngDirective</a> annotation class for creating directives has some additional logic. Like the other ngBase classes the name of the directive is the first argument of the annotation constructor and the directive property object as the second argument. The constructor of the annotated class automatically becomes the link function on the directive object.</p>

<pre><code class="language-javascript">@ngDirective('hello', {
  scope : true,
  template : '&lt;div&gt; hello {{data}}&lt;/div&gt;',
  restrict : 'AE'
})
@ngInject(['data'])
export class hello {  
  constructor(data) {
    return (scope, element, attr) =&gt; {
      scope.data = data();
    }
  }
}
</code></pre>

<p><strong>The Bootstrapper</strong></p>

<p>Annotations can bind behavior to a class, and we can process the behavior by looking at injectable dependencies. The <a href="https://github.com/SergeiGolos/CodeOfSerge/blob/master/script-annotation-and-angular-1x/src/lib/ngBootstrap.ats">ngBootstrap</a> class processes a list of imports. In our bootstrapping process, this is denoted by arguments based on how Tracuer transpiles this code.</p>

<pre><code class="language-javascript">import {ngBootstrap} from './lib/ngBootstrap';  
import {data} from './data';  
import {main} from './main';  
import {hello} from './hello';

var app = ngBootstrap(document, angular.module('test', []), arguments);  
</code></pre>

<p>Transpiled, we get this code, which explains the argument's object.</p>

<pre><code class="language-javascript">define(['./lib/ngBootstrap', './data', './main', './main2', './hello'], function($__0,$__2,$__4,$__6,$__8) {  
  "use strict";
  if (!$__0 || !$__0.__esModule)
  $__0 = {default: $__0};
  if (!$__2 || !$__2.__esModule)
  $__2 = {default: $__2};
  if (!$__4 || !$__4.__esModule)
  $__4 = {default: $__4};
  if (!$__6 || !$__6.__esModule)
  $__6 = {default: $__6};
  if (!$__8 || !$__8.__esModule)
  $__8 = {default: $__8};
  var ngBootstrap = $__0.ngBootstrap;
  var data = $__2.data;
  var main = $__4.main;
  var main2 = $__6.main2;
  var hello = $__8.hello;
  var app = angular.module('test', ['ngRoute']);
  ngBootstrap(document, app, arguments);
  return {};
});
</code></pre>

<p><strong>Conclusion</strong></p>

<p>You can find running code examples <a href="https://github.com/SergeiGolos/CodeOfSerge/tree/master/script-annotation-and-angular-1x">here</a></p>

<p>This post gave a real world example of the usefulness of data annotation. But there is a lot more. There are benefits to decoupling the application from Angular. The annotation can be quickly re-writen to bind a different framework to your current classes. There are benefits to unit testing a directive without needing to bind to angular.</p>

<p>Overall, data annotation is a tool for the tool box, and more posts will come on how this tool is useful.</p>]]></description><link>http://codeofserge.com/script-annotation-and-angular-1x/</link><guid isPermaLink="false">3d028ba6-63c5-41b8-a56f-10123a34b34e</guid><category><![CDATA[@script]]></category><category><![CDATA[annotation]]></category><category><![CDATA[angular]]></category><category><![CDATA[requirejs]]></category><dc:creator><![CDATA[Sergei Golos]]></dc:creator><pubDate>Tue, 13 Jan 2015 03:20:00 GMT</pubDate></item><item><title><![CDATA[@script, annotation for the win]]></title><description><![CDATA[<p>While everyone is fawning over Angular 2.0, it isn't something we can really use for a while. But Tracuer and @script are here, and--as long as you support IE9 and up--they are here for you today.</p>

<p>The Angular team published a playground for @script: <a href="https://github.com/angular/atscript-playground">https://github.com/angular/atscript-playground</a></p>

<hr>

<p><strong>So why is annotation-oriented programing so much win?</strong></p>

<p>The quick answer is meta programing. <em>Buzz word alert</em>: The basic idea is that you can mark up some object in your code with additional meta-information. And the cool part: parse that mark up at runtime to give your application additional intelligence.</p>

<p>But lets take a quick look:  </p>

<pre><code class="language-javascript">// An annotation class that defines an animal
class animal {  
  constructor(sound) {
    this.sound = sound;
  }
  speak() {
    console.log(this.sound);
  }
}
</code></pre>

<p>An annotation is really just the instantiation of some class that can be bound to an 'annotations' property on the target class.  The above code created an annotation class called "animal."  When instantiating a class, we can create animal with a custom sound.  As the example bellow shows, the @script annotation syntax allows us to attach the annotation class of "animal" to any classes we create like "cow" or "dog" targets.</p>

<pre><code class="language-javascript">// Create a cow class an annotate it with a cow sound.
@animal('Mooo')
class cow {  
}

// Create a dog class and annotate it with a dog sound.
@animal('Woof')
class dog {  
}
</code></pre>

<p>This is @script transpilation; the @animal('Woof') actually translates to the following JavaScript.</p>

<pre><code class="language-javascript">var dog = function dog() {};  
($traceurRuntime.createClass)(dog, {}, {});
Object.defineProperty(dog, "annotations", {get: function() {  
  return [new animal('Woof')];
}});
</code></pre>

<p>After the classes are marked up with annotation, a new property, 'annotations,' becomes available on the class object. It is an array, allowing for multiple annotations to be applied to a class.</p>

<pre><code class="language-javascript">cow.annotations[0].speak() //=&gt; Mooo  
dog.annotations[0].speak() //=&gt; Woof  
</code></pre>

<p>This is nothing revolutionary, but it does create a great convention, allowing us to write code that describes itself to itself.  Lets take a look at a way that this can be consumed. In the code example,  <a href="https://lodash.com/">lo-dash</a>, it is used for writing functional code, I am a lambda whore.</p>

<pre><code class="language-javascript">_.each([cat, dog, table], c =&gt; {  
  var noop =  { speak : () =&gt; {}};
  (c.annotations || [ noop ])[0].speak();
  });
</code></pre>

<p>Each loop can process the individual classes for the annotation property. In more complicated workflows, this can take into account the different annotation classes.  </p>

<p><strong>Conclusion</strong></p>

<p>You can find running code examples <a href="https://github.com/SergeiGolos/CodeOfSerge/tree/master/script-annotation-for-the-win">here</a>.</p>

<p>The code example above is not very useful, since any number of polymorphic practices can resolve this problem in much cleaner ways. But it does show how annotations can create behaviors on classes that you may not have the rights to change.  Annotation also get out of the way of the implementation, allowing you to attack cross cutting concerns without affecting the annotated class.</p>]]></description><link>http://codeofserge.com/script-annotation-for-the-win/</link><guid isPermaLink="false">eaf7c335-db02-4a7e-84b3-d0f72e59ee67</guid><category><![CDATA[@script]]></category><category><![CDATA[annotation]]></category><dc:creator><![CDATA[Sergei Golos]]></dc:creator><pubDate>Wed, 03 Dec 2014 00:27:13 GMT</pubDate></item></channel></rss>