Friday, August 1, 2014

A short lesson on Angular scopes and prototypal inheritance

Consider the following simple Angular app:
angular.module('watchingApp', [])
    .controller('watchedController', function($scope) {
	$scope.value = 9;
.controller('watchingController', function($scope) { });

This creates two controllers and one of them stores a value. Here is some HTML that uses these controllers:

<div ng-controller="watchedController">
  Outer value is {{value}}.
  <br />
  <div ng-controller="watchingController">
    Inner value is {{value}}.
    <br />
    <textarea ng-model="value">{{value}}</textarea>

The full snippet can be found on github.

The expected behavior is that if you type in the textarea, both the outer value and the inner value are updated to reflect the new value. However, this is not happening. On any change to the textarea, only the inner value is updated. Try it yourself:

Value is {{value}}.
Value is {{value}}.

So, what is happening? Why is only one value being updated? How can we fix this?

Before answering these questions, let's show another, slightly more complex example:

Value is {{value}}. This value and the next are always the same.

These next two values start the same, but after clicking one of their buttons,
they diverge from the outer values.
What is going on?

You can find the full code on github. Here is a concise explanation of what is going on. We define a simple controller, as before. We also define a directive that displays a value and a button. The button, when clicked, will increment the value.

angular.module('watchingApp', [])
    .controller('watchedController', function($scope) {
	$scope.value = 9;
.directive('watching', function() {
	return {
		restrict: 'E',
		scope: {
			value: '='
		link: function(scope, element, foo) {
			scope.clicked = function() {
				scope.value = scope.value+1;
		template: '<p>My value is {{value}}<br/><button ng-click="clicked()">Click me!</button></p>'

The HTML uses the controller once and the directive several times:

<div ng-controller="watchedController">
  Value is {{value}}.
  <watching value="value"></watching>
  <div ng-if="true">
    <watching value="value"></watching>
    <watching value="value"></watching>

The naive expectation of this code is that clicking on any button will increment all values, but this is not the actual behavior. Try it yourself. What is happening here?

For those reading closely, you will see that there is a use of the ng-if directive. ng-if adds a child scope and that is a clue as to why things behave differently.

Here's the explanation.

Child scopes use the parent scope as its prototype. This way, every property available on a parent scope is also available on the child scope. It's a wonderfully elegant solution to ensuring that nested scopes are...well...nested. However, when a property is set, it is always set on the current scope not the enclosing scope. This allows properties on the current scope to shadow properties on enclosing scopes. Shadowing is one of the fundamental concepts of Javascript. A very simple example:

var Dog = function() { };
Dog.prototype = {
	greeting: 'bark.',
	greet: function() { console.log(this.greeting); }

new Dog().greet(); // bark.

var angryDog = new Dog();
angryDog.greeting = 'grrrrr.';
angryDog.greet(); // grrrrr.

When reading a property, if the current object does not define it, its prototype object is checked. When writing a property, the current object is always the target of the write, even if the property already exists in the prototype. Angular scopes are exactly the same. scope.value = scope.value+1 will always write to the current scope, even if value is defined in an enclosing scope. Similarly, the ng-model directive will always bind to the current scope, regardless of whether or not the property is defined in an enclosing scope.

So, how do we fix this problem?

The first observation to make is that if you find that your app is mutating the state of enclosing scopes, then this is a code smell and you should be refactoring to avoid this.

If you find that mutating enclosing state is unavoidable, then you must explicitly set the state on the enclosing scope instead of the current scope. In the first example, you would set the model to be the parent scope, like this:

<textarea ng-model="value">{{$parent.value}}</textarea>

This works, but is fragile and inelegant, since you need to be careful that the value you are setting is actually in the enclosing scope, and not the enclosing enclosing scope. This can happen by accident if the textarea gets wrapped in an ng-if or other directive that adds a new scope to the chain.

This problem of accidentally writing a property to a scope instead of an enclosing scope is subtle for novice users of the Angular framework and can appear unexpectedly (it has bitten me once or twice). The best advice is to avoid mutating enclosing state wherever possible.

It is not possible to truly understand angular without understanding how scopes are created and nested, and the ramifications that this has on the apps that you create.

Wednesday, July 23, 2014

Warning: AngularJS Modules are not Modular

In most frameworks and languages, a module's exports are only visible to the other modules that directly import it. As a simple example, the following node.js program prints undefined:




exports.myVal = 7;



> node parent.js

Ignoring the fact that circular dependencies are evil, a novice node user would realize why the printed value is undefined. The reason is one of the defining characteristics of the node module system (actually, it is a characteristic of most module systems ever created). Modules must explicitly declare the modules that they use. Referencing values from modules that are not explicitly required will result in undefined values or errors.

This is not so with AngularJS.

The Angular module system provides some nice syntax to describe required modules. For example, this says that the parent module uses the sub1 and sub2 modules:

angular.module('parent', ['sub1', 'sub2']);

Now, let's assume that sub1, and sub2 each declare no dependencies:

angular.module('sub1', []);
angular.module('sub2', []);

Using just about any other module system as a guide, you would expect that code from parent can reference (i.e., inject) values from either sub1 or sub2, but neither of the sub-modules can reference values from each other or parent.

But, no. That is not the case. Consider that this is added to the app:

.run(function(sub2Value) {

angular.module('sub2').value('sub2Value', 'I should be an error!!!');

Referencing sub2Value from module sub1 does not cause an error even though its module is not directly referenced. Rather, the program prints "I should be an error!!!" to the console. Try it out yourself.

What's going on here?

Each Angular application has a singleton instance of an injector. This injector is not namespaced or partitioned. All instances provided by all modules in the application exist in the injector. And the injector can serve any of its instances to anything that requests it.

You can see that similar behaviour in Guice:

class ModuleMain {
    static class Service1 {    }

    static class Module1 implements Module {

        public void configure(Binder binder) {

    static class Service2 {

        Service1 service1;

    static class Module2 implements Module {

        public void configure(Binder binder) {

    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new Module1(), new Module2());

        Service1 service1 = injector.getInstance(Service1.class);
        Service2 service2 = injector.getInstance(Service2.class);
        // Will print true since instances from unrelated modules can reference each other
        System.out.println(service2.service1 == service1);

In this snippet, you can see that instances can be shared across unrelated modules. In Guice, like in Angular, the injector is a giant bucket where you can put stuff in and take stuff out with no restrictions.

But, there is a difference. In Angular, modules explicitly declare which modules they depend on, but not in Guice. In Angular, the syntax provides the expectation that only instances from directly required modules can be injected into another module. I am sure that there is a reason for this non-intuitive design, and I would like to learn it.

Consider this post as an explanation of what is going on, but not why. Also, consider this a warning to not rely on the Angular framework to enforce module boundaries. Perhaps in a future version, the Angular team can create truly hierarchical modules. Angular modules would be safer to compose, and name clashes between third-party modules would be prevented.

Wednesday, March 12, 2014

Unshackling Mylyn from the Desktop

Next week at EclipseCon, I'll be giving a talk with Gunnar Wagenknecht on our side project to bring a hosted task list to Mylyn. This is something that I'm really excited about and it will be the first time we are discussing this project in public. The Mylyn project was a truly ground-breaking project when it first became an Eclipse project back in 2005. It revolutionized the way that developers work with and manage the over-abundance of information in the IDE. Now, even though it is still a well-used and loved project, it has not been evolving at the same rate that developers' expectations have. Since being introduced, developers tend to be less tied to their IDE, using git on the command line, github in the browser, and email on a tablet. However, the Mylyn task list is stuck in the IDE.

In our presentation, we’ll be demoing a hosted task list, that can gather tasks from multiple task repositories (Jira, Bugzilla, etc), store them on a server, and then provides an open API to interact with them. The API is open, using a mix of REST and websockets, and this is the interesting part since the API allows you to build clients that interact with your task list in ways that were never possible before.

If you’re interested, I hope you’re coming to EclipseCon so you can see our talk. If not, you’ll have to wait until later when I have some time to write a proper blog post about this.

Thursday, June 6, 2013

Where's the memory leak?

A few days ago, I was tracking down a memory leak through Yourkit and I was pointed to this code (vastly oversimplified, but just complex enough to prove my point):

This code is part of a compiler and stores some metadata on an Abstract Syntax Tree node during byte-code creation. The profiler told me that there were thousands of ClosureWriter instances being kept around for the length of the compile (roughly one for each closure defined in the program). While not a huge amount of memory, this bothered me. For a while, I couldn't figure out why these references stuck around. Then it occurred to me that each reference to ClosureWriter.UseExistingReference.class keeps a back pointer to the enclosing ClosureWriter instance. By changing the UseExistingReference to static, the leak disappeared.

What's the lesson?

In Java, always, always declare your inner classes as static unless you are sure that you need back references to the enclosing instance.

Friday, November 23, 2012

What is this cloud thing?

Here are the slides from my UBC alumni presentation on programming for the cloud.

You can also download the demo code that I wrote during the talk here on github.

Thank you all who came. It was a lot of fun to give the talk.

Saturday, November 17, 2012

Lots of beer, pizza, and coding

Lots of beer, pizza, and coding. I'd say that our second Vancouver Eclipse hackathon was a huge success. We had committers from several Eclipse and Eclipse based projects: Mylyn, p2, JDT, Orion, and Scripted were all represented. We had 30 hackers spread across all of these projects. Currently, we have 7 patches that have been accepted into codebases, and three more that are working their way through the submission process.

The hackathon was a great and social way to be introduced into the open-source world and perhaps some of these new Eclipse contributors can become Eclipse committers. If you are interested in holding an Eclipse hackathon (or any hackathon) in your area, feel free to contact me. I now know what works and what doesn't.

Just getting started

All working hard

Nieraj and Leo take a moment to relax

Ian Skerret, flew all the way from Ottawa for us

A big thank you to all the project leads who helped (and are still helping) some newcomers fixing their first bug. And an even bigger thank you to everyone who worked hard and stayed up late, just to do some coding. It was a lot of fun.

For another look at the hackathon and more photos, see the Tasktop blog.

Thursday, November 1, 2012

JSDoc is more than just documentation (in Scripted)

Recently, we released the Scripted editor for editing your JavaScript. It's still early stages, but our focus on a light-weight and semantically aware editor already has some compelling features. In this blog post, I'll show you how you can use JSDoc in your JavaScript files to provide Scripted with some inferencing help. Since Scripted uses the Orion editor, most of this JSDoc support is also available in Orion.

There are many flavors of JSDoc and there is no standard, but the Google Closure Compiler uses a style that is well-documented, self-consistent, and complete. We use Doctrine as the JSDoc parser, which has a complete understanding of the JSDoc annotations of the Closure Compiler.

Currently, Scripted recognizes a subset of JSDoc tags:

  • @type {type-sig} {optional-doc} specifies the type of a variable declaration
  • @param {type-sig} {param-name} {optional-doc} specifies the type of a function parameter. Parameter annotations are not positional. They must correspond to an actual named argument of the function.
  • @return {type-sig} {optional-doc} specifies the return type of a function

The docs for the Closure Compiler specify many kinds of type signatures. Only a subset are relevant to and supported in Scripted. Scripted recognizes:

  • Simple types, eg- {Window}, {boolean}, {Boolean}
  • Record types, eg- {{myNum: number, myObject}}
  • Function types, eg- {function(arg0:string,arg1:boolean)}
  • Function return types, eg- {function():number}

And of course, type signatures can be combined to produce more complex signatures. The built-in types boolean, number, string, and object can optionally be capitalized, this breaks from the semantics of the closure compiler, but provides more flexibility to programmers. Other kinds of signatures are tolerated, but do not affect the inferred type.


With this information, we can start showing some examples. Scripted uses typing information for hovers, navigation (e.g., CTRL+Click to navigate to definitions), and for content assist.

Simple @type

Here is a simple JSDoc comment to define a string variable:

Record types

Using a record type signature, you can define the type of an object literal:


You can specify that a variable is a function, as well as include its parameter names and return types (parameter types are currently ignored for function type signatures). It looks like this:

If you want to declare the types of function parameters, then you should be using the @param annotation, like this:

User defined types

User defined types are recognized as well:

Union types

One possible point of confusion is with union types. They are interpreted by Scripted as whatever the first signature is. So, in the following is interpreted as a string:

Node support

And finally, Scripted's JSDoc support can be combined with its dependency analysis to infer types defined in other modules. This is extremely helpful for node projects where the use of callbacks can obscure the parameter types. In the following example, by specifying the types of the req an res parameters, you can get some meaningful content assist for them:

What's next

There are some more interesting cases that we should handle. A common idiom in JavaScript is to declare constructors using qualified names. Libraries like Dojo and Ext JS. For example, you can define a class name in Ext JS like this:
Ext.define('scripted.Widget', { ... });

And in Dojo:

var Widget = dojo.declare('scripted.Widget', [], { ... });

We could accomplish this using the @typedef annotation or possibly the @constructor annotation.

Additionally, the @lends annotation provides a nice way to specify options and configuration for constructing types and will likely make it into an upcoming version of Scripted.


Using JSDoc in your JavaScript files is a good way to give some extra help to the inferencer, which often has trouble recognizing some of JavaScript's more dynamic features. Scripted is still in its early stages, and is moving ahead quickly. We like feedback. You can send a message to the Google group and fork us on Github.