Aug 26, 2015

Minimize the price of type in Typescript

I watched Anders Hejlsberg introduce typescript in 2012. Then I thought I don't have the problem it tries to solve. Type in Javascript has not yet caused any problem, as I have unit test, renaming and intellisense is also not a problem for me, because I have webstorm. Then, I found that Douglas Crockford said something in google plus

Microsoft's TypeScript may be the best of the many JavaScript front ends. It seems to generate the most attractive code. And I think it should take pressure off of the ECMAScript Standard for new features like type declarations and classes. Anders has shown that these can be provided nicely by a preprocessor, so there is no need to change the underlying language.

I think that JavaScript's loose typing is one of its best features and that type checking is way overrated. TypeScript adds sweetness, but at a price. It is not a price I am willing to pay.

I was kind of thinking the same way. So I didn't use Typescript in my all my projects until 4 months ago, when I joined a angularjs project where typescript is designated to be used. Now after using typescript for four months, I feel that, type can be your burden if it is not used properly, but it can be good enhancement of Javascript if used in the right way. In the following, I will list some of bad and good example of using typescript, the good examples try to reduce the cost of using type in typescript.

Don't create unnecessary type annotation, use inference.

interface IPerson {
   firstName: string,
   lastName: string
}

 function printPerson(person:IPerson) {
  console.log(person.firstName + ',' + person.lastName);
 }

//bad
var i: number = 1;
var john: IPerson = {
  firstName: 'John',
  lastName: 'Doe'
};

printPerson(john);

//good, because Typescript compiler can infer type of i and the literal object.
var i = 1;
var john = {
  firstName: 'John',
  lastName: 'Doe'
};

printPerson(john);

Don't create unnecessary interface or class, use inference

//bad, you need to duplicate type information from the object
interface Customer {
    firstName: string,
    lastName: string    
}
function createCustomer():Customer {
  return {
     firstName: 'John',
     lastName: 'Doe'
   };
}

//good, typescript compiler can infer the return type
function createCustomer(){
  return {
     firstName: 'John',
     lastName: 'Doe'
   };
}

Don't create interface if "named anonymous type" is available

//bad, you need to duplicate the type information from the object
namespace demo {
     
    export interface Settings {
          svcUrl: string
    }

    angular.module("demo").value("settings", {
         svcUrl: 'http://foo.com'
    });
}
//good
namespace demo {
    var settings = {
         svcUrl: 'http://foo.com'
    };

    export type Settings = typeof settings;
    angular.module("demo").value("settings", settings);
}
//
namespace demo {
    //use settings with type annotation 
    angular.module('demo').controller('main', function (settings: Settings) {
       console.log(settings.url);
    });
}

Don't create class if all you need is an interface, because typescript is using duck typing

//bad
class Customer {
    firstName: string;
    lastName: string ;
}

//good
interface Customer {
    firstName: string;
    lastName: string ;
}

function logCustomer(cust: Customer) {
   console.log(cust.firstName + ', ' + cust.lastName);
}

Don't use multiple assignment to define an object, use object literal expression

//bad, because typescript cannot infer the type of return object
function createCustomer () {
   var rtn : any = {};
   rtn.firstName = 'John';
   rtn.lastName = 'Doe';
   return rtn;
}

//good, because typescript can infer the literal object
function createCustomer () {
    return {
        firstName: 'John',
        lastName: 'Doe'
    }
}

Don't use module if it is internal module, use namespace

//bad 
module demo {

}

//good
namespace demo {

}

Don't use complicated construct, if simple construct is good enough

namespace demo {
    //bad
    export class Data {
        public static get key1(): string { return "value1"; }
        public static get key2(): string { return "value2"; }
    }

    //good
    export var data = {
        key1: 'value1',
        key2: 'value2',
    }
}

Aug 24, 2015

TypeScript is duck typing.

When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.

Typescript a superset of typescript, since Javascript is a duck typing language, typescript is also a duck typing language. In strong type languages the signature of an object is important and type is the signature of an object, they care about whether the signature are compatible. Typescript does not care about signature and type, cares about whether objects are replaceable because of what they can actually do.

Typescript interface is not a signature but semantics

Type compatibility in TypeScript is based on structural subtyping, it relates types based solely on their members. In the following example, variable foo and bar are declare of different interface type. The literal object can be assigned the variable foo, because typescript compiler can infer the ability of the literal object(this is called type inference), and typescript compiler think that literal object can do what interface is expected to do. And foo can be assigned to bar, because foo can do what interface Bar is expected to do. The name of interface (Foo and Bar) does not matter, what is matter is semantics of the interface.

//--interface is semantics
interface Foo {
  quack();
}

interface Bar {
  quack();
}

var foo : Foo;
var bar: Bar;

foo = {
   quack: function () {}
};

bar = foo;

Typescript class is just an interface with implementation

One of the reason that people use Typescript is that it support class. However, typescript class is different from C# and Java class. The following are similar to Java class. You can create an instance of a class by using the keyword "new", you can inherit a class by using keyword "extends".

//--class as implementation
class Duck {
    constructor(public name: string) {
    }
    quack() {
        console.log('Duck quack ' + this.name);
    }
}

class Swan extends Duck {
    fly() {
        console.log('Swan fly ' + this.name);
    }
}

var duck = new Duck('duck1');
duck.quack();
//
var swan = new Swan('swan1');
swan.quack();
swan.fly();

But a less well-known fact is that typescript class can be used as an interface, like the following code

//---class as interface----
var objectOfAnounymousType = {
    name: 'Daisy',
    quack: function () {
        console.log('quack quack ' + this.name);
    }
};
var daisy: Duck = objectOfAnounymousType;
daisy.quack();

class Person implements Duck {
    name = "Person"
    quack() {
        console.log('Person quack ' + this.name);
    }
}

var john = new Person();
john.quack();

daisy = john;
daisy.quack();

When typescript compiler see the a literal object, it can infer an anonymous type from the object. When the object is assigned to a variable of Duck class, typescript compiler find that the anonymous type is compatible to Duck class(interface) because the anonymous type has all the members that Duck class has. The class Person does not extend (inherit) Duck class, instead it treat Duck class as an interface, and implements it.

The difference between interface and class is that interface does not has implementation but class has implementation. Because of this, class can implement interface, but interface can not implement interface.

interface IDuck {
    name: string,
    quack: () => void
}

interface ISwan extends IDuck {
    fly(): void
    
}

class Duckling implements IDuck {
   constructor(public name: string) {
    }
    quack() {
        console.log('Duckling quack ' + this.name);
    }
}

Thanks for taking the time to read this. Feedback, critiques and suggestions are welcomed.

Aug 20, 2015

Leave $rootScope alone, use AngularJs Dependency Injection.

AngularJs brings dependency injection into UI development. It works very well until it is misused. Recently, I was working on an AngularJs project. One interesting thing is that some application settings is attached to $rootScope for convenient consumption. When I saw it, I felt this was so Déjà vu. The $rootScope has essentially become the new "window" object in the browser, where all global variables can be attached to. So I Googled about this and wanted to know whether other people have similar problem, and I found this question in StackOverflow, Global variables in AngularJS. It seems that this is a quite a common problem out there. So I wanted dig into it more.

In the article Global Variables Are Bad, a few bad reasons were listed for using global variables.

  1. "What's a 'local variable'?"
  2. "What's a 'data member'?"
  3. "I'm a slow typist. Globals save me keystrokes."
  4. "I don't want to pass it around all the time."
  5. "I'm not sure in what class this data belongs, so I'll make it global."

I think the the reason we want to attach variables to $rootScope is because of #3 and #4 of the reason above. I don't need to argue why Global variables are bad, because the article has very good coverage. But in case of AngularJs, by changing the dependency on "setting" to "$rootScope.setting", the dependencies of "setting" become implicit. This is bad for communication, documentation, and maintenance. And it will encourage dumping more dependencies into $rootScope. The advantage of AngularJs dependency injection is completely gone. Explicit dependencies become exploring dependencies in the dark world of $rootScope.

One more possible reason in using $rootScope is that it makes the databinding easier, because all child scopes will inherit $rootScope's properties. But this only works when the child scope is not isolated scope. This practice will discourage the use of isolated scope, which is a great way to improve reusability of your directive.

Using inheritance from parent scope and $rootScope is very fragile and heavy coupling. A better way is to use dependency injection. Let's see an example, which is over-simplified. It may violate the best practice of AngularJs you have learned from somewhere else. But the point is to demonstrate the difference between using global variable and dependencies injection.

So the demo app wants to show a user a login screen if the user is not logged in, otherwise a welcome screen. Simple enough. The following is the implementation using global variable. You can see the code at http://output.jsbin.com/monozu. This implementation creates a global variable attached to $rootScope, which is visible to child scopes.

  <div ng-controller="login">
    <div  ng-if='!user.isAuthenticated'>
      You are not logged in yet.
      <button ng-click="user.login()">
        Log in
      </button>
    </div>
  </div>
  
  <div ng-controller="welcome" >
   <div ng-if='user.isAuthenticated'>
      Hello, {{user.firstName + ',' +  user.lastName}}
    </div>
  </div>
  var app = angular.module('app', []);
  
  app.run(function ($rootScope) {
    $rootScope.user = {
      isAuthenitcated: false,
      login: function () {
        this.firstName = 'John';
        this.lastName = 'Doe';
        this.isAuthenticated = true;
      }
    };
  });

app.controller('login', function ($scope) {

  });
  
  
  app.controller('welcome', function ($scope) {

  });

The following is the implementation using dependency injection. You can see the code at http://output.jsbin.com/senuti. The html template is still the same, but in JavaScript, the user global variable is removed from $rootScope, and become a service, which is injected into to each controller.

  app.factory('user', function () {
    return {
      isAuthenticated: false,
      login: function () {
        this.firstName = 'John';
        this.lastName = 'Doe';
        this.isAuthenticated = true;
      }
    };
  });
  

  app.controller('login', function ($scope, user) {
    $scope.user = user;
  });
  
  
  app.controller('welcome', function ($scope, user) {
    $scope.user = user;
  });

The implementation using dependency injection may use a little more code, but is more testable, maintainable and scalable. Please comment and let know what you think.

Jul 8, 2015

Class in ES6, Typescript, Angular2 and Angular1

ES6 class

Class was proposed in ECMAScript 4, which was abandoned, and ES5 does not have Class. Now ES6 is finalized and it has class.

So what is the big deal of it? Should I use it? Will it change the nature of JavaScript? Here is an excerpt from ECMAScript 2015 specification

Although ECMAScript objects are not inherently class-based, it is often convenient to define class-like abstractions based upon a common pattern of constructor functions, prototype objects, and methods. The ECMAScript built-in objects themselves follow such a class-like pattern. Beginning with ECMAScript 2015, the ECMAScript language includes syntactic class definitions that permit programmers to concisely define objects that conform to the same class-like abstraction pattern used by the built-in objects.

It turns out, ES6 class is essentially a constructor function (which should be called with "new" keyword), it still uses prototype inheritance Here is some test case which is used in ES6 compatibility table, which also confirms this.

 class C {}
 return typeof C === "function";

return typeof class C {} === "function";

return typeof class {} === "function";

The question of "Should I use ES6 class or closure function?" is essentially "Should I use constructor/prototype or closure function". If you google constructor/prototype vs closure function, you can find lots of discussion about this, such as Efficiently creating JavaScript objects: closures versus prototypes, Some Javascript constructor patterns, and when to use them and of course Douglas Crockford's Private Members in JavaScript.

Developers of classical language tend to love ES6 class, maybe because class is the familiar way to create object. It is true that ES6 class(prototype) use less memory when you create thousands of instance of one class with shared methods (which can be factored out prototype object), but most of the time, I just need to create one instance adhocly. Also JavaScript runtime like V8 will create hidden class anyway when it finds that two objects has the same shape, and also memory is really cheap nowadays, so memory efficiency is not really important here.

Another advantage of ES6 class is that it simplify inheritance, if you really need to use inheritance as reusability vehicle like EmberJs or BackboneJs, this is really a good reason to use ES6 class. But the bigger problem is that inheritance is really bad idea.

Closure is confusing to classical language developer, but Douglas Crockford claim it is the best idea in the history of programming language. To me, closure is more flexible, readable, powerful and it supports encapsulation and does not require to use the "this" variable. I really like Douglas Crockford's class-free object-oriented programming.

Class in TypeScript and Angular 2.0

Angular team is now building Angular2 with Typescript. In Angular2, we can write application using ES6 class with typescript . If you follow the quick start guide of Angular2, you will find some code like the following.

/// <reference path="typings/angular2/angular2.d.ts" />

import {Component, View, bootstrap} from 'angular2/angular2';

@Component({
    selector: 'my-app'
})
@View({
    template: '<h1>My first Angular 2 App</h1>'
})
class AppComponent {

}
bootstrap(AppComponent);

In Angular1, we use closure to create service, controller, directive. In angular2, angular team seems to use class extensively. Why? In the Keynote on AtScript at ng-europe 2014, Misko (the creator of Angular) described the problem in angular1 is that angular1 API is too complicated to use. They want to have a better abstraction and simpler API. Angular team decided to use lots ES6 features such as class, module. But these features are not enought. So they want to extend the language by creating AtScript. The following is relationship between AtScript, TypeScript, ES6, and ES5. The feature they really want are "Annotation" and "Introspection", these features allow you declaratively add functionality to your class.

Later, Angular team communicate to typescript team their needs in typescript. Since typescript 1.5 start to support class with decorator ( which is essentially the annotation in AtScript), Angular team cancel AtScript and use typescript to write Angular2.

How can class with decorator simplify the Angular2 api? In the above code, the class is annotated with decorator, which is pretty neat. This code is transpiled to the following javascript (ES5)

var __decorate = //omit some implementation

var angular2_1 = require('angular2/angular2');
var AppComponent = (function () {
    function AppComponent() {
    }
    AppComponent = __decorate([
        angular2_1.Component({
            selector: 'my-app'
        }),
        angular2_1.View({
            template: '<h1>My first Angular 2 App</h1>'
        })
    ], AppComponent);
    return AppComponent;
})();
angular2_1.bootstrap(AppComponent);

We can see that the decorator can modify the class definition declaratively. So class with decorator in typescript is good. Actually decorator is already proposed in ES2016, so we may see decorator get standardized very soon.

Class in Angular1

So how about class in Angular1 ? Can we use class to simplify our code or improve performance in Angular1? After "Angular 2: Built on TypeScript" announced, people are thinking of future-proof way to write code with angular1. Obviously Angular2 is using class, a lot, should we use class now in Angular1. From the very beginning, we use closure to create Angular1 component, now some Angular1 projects switch to use class exclusively to replace closure. Suddenly, it seems that closure is obsolete in Angular1, is it?

First, angular1's architecture has not changed and will keep the same in the future, the change will be in Angular2. Angular1 is still using closure internally to create service, directive, controller. If you use class in Angular1, it will not simplify our code, it may even add some complexities to your code. Secondly, angular1 does not use class or class with decorator internally, there is no advantage in that sense.

In the following, I will implement a service, a controller and a directive using class and closure and compare them side by side. And the code is written in typescript, because it support ES6 class and optional type. The source code above can be found https://github.com/fredyang/class-or-closure-angular1, the demo page can be found here.

First let's see take a look on service. If we want to use class to define service in angular1, we should use module.service method, because I want to use the class directly. If we use closure, we should use module.factory.

// common interface of Backend service
// implementing it seems to be good idea, it is used by
//both ClassBackend and closureBackend
interface IBackend {
    login(userName: string, password: string) : ng.IPromise
}

///-------service implemented by class---
class ClassBackend implements IBackend {
    //save $q for reference
    constructor(private $q) {
    }
    login(userName: string, password: string) {
        //access $q via 'this' reference
        return this.$q.when(password === '123');
    }
}

//use module.service method, as it will use 'new' to call class ClassBackend
// which it is essentially a constructor function
angular.module('app').service('classBackend', ClassBackend);


///------service implemented by closure----
angular.module('app').factory('closureBackend', function ($q): IBackend {

    return {
        login: function(userName: string, password: string) {
            //access $q via closure
            return $q.when(password === '123')
        }
    };

});

Now let's implement controller. Here, we can use class to define controller directly, because angular1 treat controller as constructor.

///common interface of controller
//implementing IUser is optional, seems the expression
//in html view is not strong typed yet.
interface IUser {
    isAuthenticated: boolean;
    userName: string;
    password: string;
    login(): ng.IPromise
}

///------controller implemented by class-----------
class ClassController implements IUser{
    constructor(private classBackend:IBackend) {
    }

    isAuthenticated = false;
    userName = 'Fred Yang';
    password = '123';

    login() {
        return this.classBackend.login(this.userName, this.password)
            .then((isAuthenticated) => {
                //need to arrow function to access 'this'
                this.isAuthenticated = isAuthenticated;
                return isAuthenticated;
            });
    }
}

angular.module('app').controller('ClassController', ClassController);

/////---------controller implemented by closure--------------
angular.module('app').controller('ClosureController',
    function (closureBackend:IBackend) : IUser {

    //here I want to avoid to use "this.xxx = yyy"
    // and explicitly return an object instead implicitly return this
    // so that I can use closure
    var rtn = {
        isAuthenticated: false,
        userName: 'Fred Yang',
        password: '123',
        login: function () {
            return closureBackend.login(this.userName, this.password)
                .then(function (isAuthenticated) {
                    //access isAuthenticated via closure variable,
                    //without using arrow function
                    rtn.isAuthenticated = isAuthenticated;
                    return isAuthenticated
                });
        }
    };

    return rtn;
});

Now let's implement directive. I can not use the class directly to define directive here, I still use closure function, inside which I new an instance of the class.

///------------ directive "implemented" by class --------
//implementing ng.IDirective is optional
class CounterWidget implements ng.IDirective {

    constructor(private $timeout) {
        //all the dependencies have to be attached to
        // instance "this"
        //
        // "private" just make the compiler think it is 'private'
        // but it still accessible externally in the generated
        //javascript
    }

    restrict = "EAC";

    template = "<div>counter-widget-class:{{count}}</div>";

    scope = {
        delay: "="
    };

    link = (scope, $elem, attrs) => {
        //access dependencies via "this"
        var $timeout = this.$timeout;
        //
        var delay = scope.delay || 1000;
        scope.count = 1;
        (function repeat() {
            $timeout(function () {
                scope.count++;
                repeat();
            }, delay);
        })();
    }
}


angular.module('app').directive("counterWidgetClass", function ($timeout) {
    //directive is still created using closure under the hood
    return new CounterWidget($timeout);
});


//---- directive implemented by closure ---------
//implementing ng.IDirective is optional
angular.module('app').directive('counterWidgetClosure',
    function ($timeout):ng.IDirective {
        //$timeout is closured and it is accessible to inner function
        return {
            restrict: "EAC",

            template: "<div>counter-widget-closure:{{count}}</div>",

            scope: {
                delay: "="
            },

            link: (scope:any, $elem, attrs) => {
                //
                var delay = scope.delay || 1000;
                scope.count = 1;
                (function repeat() {
                    $timeout(function () {
                        scope.count++;
                        repeat();
                    }, delay);
                })();
            }
        };
    });

From the above samples, I find that

  • The implementation in class is more complicated, verbose, rigid, it does not really encapsulate private data, but the syntax may be more friendly to java or c# developer.
  • The implementation in class is more simple, terse, flexible, and it can encapsulate private data, but it feels wired to classical developer.

Because angular2 use lots class, it does not mean that you have to use class exclusively in Angular1. Using class will not put you better place in migrating to Angular2, because Angular2 is whole new architecture. Whatever you write today in Angular1, you need to rewrite in Angular2. Until I write code in Angular2, I should still keep writing components using closure function in angular1.

Thanks for taking the time to read this. Feedback, critiques and suggestions are welcomed.

Dec 24, 2014

Some thoughts on choosing JavaScript Framework

If you are reading this post, I don't have to tell you, you already know there are tons of JavaScript frameworks out there. Some of the popular ones are shown down here. You may be overwhelmed by so many choices, and you want to choose a "best" framework for you killer app.

But the first question to ask is why you need a JavaScript framework? There are thoughts like No more JS frameworks. Some of these points might be valid. But what we need is to write our front-end code in a productive way, so that our application is testable, extensible, maintainable, scalable and performant. But unlike other platforms, this browser O/S does not have a base library, it does not have conventions and does not provide the facilities to do that. You may agree with "No more JavaScript framework", but you still need to achieve these goals, and most likely you will create your own JavaScript framework, convention, structure or whatever you want to call it.

Although the platform does not have the facilities you want, yet it is very open and encourages you to create your framework. It turns out, creating your JavaScript framework is fun and relatively easier, as I personally created one. But if you don't like the idea for whatever reason, you need to pick one from others.

How to pick a JavaScript framework is affected by your role and your competence of JavaScript. Are you a CTO, development manager, architect, or front-end developer, back-end developer (yeah, so cool that back-end controls front-end, who doesn't like inversion of inversion of control)? Are you a JavaScript Ninja or beginner or somewhere in between. Have you created a JavaScript( or any kind of) framework? Do you just like standing on the shoulders of giants and purely consuming other people's work?

If you don't know JavaScript...

...but are in a position to approve or reject a framework, I suggest that you don't do that. But if you really want to or even don't want get your hands on any code, you may do the following.

  1. Google which is the best javascript framework, follow the top 20 links and read them
  2. Go to the frameworks' home page and find their success cases and count their number, for example Backbone.js's success cases, AnguarJs's success cases, Ember.js's success cases. If some of these success cases appeal to you, don't jump to the conclusion to use that framework, because very likely at the time you are reading the post, the company might have already switched to use another framework. People tend to brag about their success but not failures. If people are doing something that seems to be the right choice in the beginning, and they tell you immediately, but later when they found that it is a wrong choice, they will not tell you. Five years ago, I was asked to join a company to develop an Silverlight application. This year, I was asked by them to rewrite their app based on the web platform. Two years ago, a company asked me to join them develop their killer app using b.js, and this is the same company that asked me to them to migrate their app from b.js to a.js.
  3. Use Google trend to find out their popularity. A popular framework does not mean that it is a good framework, but since if you don't know JavaScript, you should trust that a popular framework is not a bad framework if it is not the best.
  4. Since most JavaScript frameworks are Open Source projects, go to their source website. Check the number of watch count, star count, fork count, contributors, and commits. You can get the sense of how the project is running. Is it actively developed or updated only for bug fixing. If a project does not have new updates, it does not mean that it is bad, maybe it means it is so perfect that no new feature needs to be added, instead you can create your framework or extension on top of it.
  5. Find out who are the people behind the framework. If you think the people behind a framework are better than the people of another one in terms of ability, then that framework may be better (not necessarily). Sometimes, the competition is not between frameworks, but the people behind. A few years ago, I liked more Steve Jobs more than Steve Ballmer, so I just bought Apple stock, but not Microsoft. Since Steve Jobs is gone, I don't buy Apple stocks anymore.

If you have some competence in JavaScript

You should choose a framework purely based on the technical aspect. You should forget about everything from above, just like the judge tells jury that their decision should not be influenced by the media. You can do the following.

  1. Go to http://todomvc.com/, download their source code at https://github.com/tastejs/todomvc , read the source to see how they implemented the same use cases, and see if it makes sense to you. Narrow down at least three choices. Then use the three choices to you implement the the same todomvc application by yourself. You can of course refer to original source code.
  2. Go to their document website and read their documents.
  3. Implement several of the most important use cases of your project with your three shortlisted frameworks. Getting your hands dirty is very important, and your effort in evaluating the frameworks that you will end out not choosing will not be wasted. Instead, it will help your to understand your domain problem, and the technical advantage of chosen framework. Most of these frameworks or libraries require you to write your application by following a convention, which is understandable, because convention means reusability, readability, and maintainability. The framework calls your code instead of you calling the framework. While you are implementing, answer questions such as: Does the convention have a deep learning curve? Does the convention require me to write lots of boilerplate code?( You want to write code fast.) Does this convention provide extensibility and does it have too much encapsulation which prevents you from achieving some "special" but really important use case? Is it easy to test my application code? Does it provide unit test support, or am I on my own to create my test infrastructure.

If you are JavaScript Ninja or framework developer

Besides the works above, you should read their source code and have a feeling of their code quality. Read their test case, if it exists. Normally, source code with test cases has higher quality. If you have a question on a feature of your framework, you can read their documents, you can go to forums asking for help, you can read books, but the best way is to find answers in their source code and the code of the unit tests. You can even fix bugs for the framework. I find that a few popular frameworks are all created by very smart people and they have very good quality code base. Just reading them can be the easiest way to boost your JavaScript skills even if you don't choose the framework.

The end

After going through all the process above, and you feel that, let's say, a.js is your choice, it is important that you know how to take advantage the best feature of it. Equally important is to its problems, gotchas, inefficiencies and solutions to overcome them. If you know both sides of a framework, and you feel the benefits outweigh its costs to develop your application, then it is a good choice.

But this is not the end. You need to invest a significant amount of time to study your chosen framework. If you don't study enough, you might feel that framework was a wrong choice after some time down the road. The reason could be that you are not using it in its best practice. Be patient. Learn from their community, read their source code. Some frameworks are "long term efficient, short term inefficient."

If you still don't like the framework or maybe there are better frameworks coming up, you need to have the courage to admit it was your mistake and switch gears, as even Mark Zuckerberg can admit a mistake. But don't blame the frameworks. Their creators unselfishly provided them for free, and their work should be respected.

I hope you choose a your JavaScript framework that works for your projects both in short term and long term.

Oct 29, 2014

Maybe the desire to control is the problem

I love to play tennis. Serve was the biggest weakness in my game. So I practice a lot, and now I am getting better and better in my serve. One of the most important techniques in serving is pronation which I struggled most with until I saw this video, The Serve Pronation Technique And 7 Drills To Learn It. Here is what strike me most in the article.

Control and letting go are, of course, at the opposite ends of the spectrum; the more you want to control, the less you will let go. While it makes logical sense to try to hit the court when you work on your serve, this desire is the BIGGEST OBSTACLE to improving your serve. You absolutely need to practice your serve technique and NOT aim in the court. Think speed, not hard. Let go, don’t control.

So why am I mention this? As a human being, we all hate to be controlled. Ironically, we all tend to love to control. This is why the world has so many conflicts. As a developer especially a front end developer, the desire to control is counter-productive. In the following, I will use a very simple example to illustrate why the controll mindset is so bad. This example was originally used by knockout.js. In the application, a user can click on a button, and two labels and another button can show or hide. It is simple but tricky enough for me illustrate my point. The following implementation in jsbin just uses vanilla jQuery. The following code is very bad, so I just want to show you part of it, I hope you can follow through.

 btnAdd.click(function () {  
    countClick++;     
    lblCount.text(countClick);
    
    if (countClick >= 3) {
      divWarning.show();
      btnAdd.attr("disabled", true);
    } else {
       divWarning.hide();
       btnAdd.attr("disabled", false);
    }
    
    lblPlural[countClick > 1 ? "show" : "hide"]();
    
  });

When I wrote this pieces of code, I was thinking from the perspective of CPU, and my desire to control is very strong. Why this code is bad? This is because a single handler has too many things to keep track. Even in this very simple application, the code is very smelly. Once the application grows bigger, the complexity of the handler will explode. One way to mitigate the problem is to use the "divide and conquer" strategy, where an upper controller delegates the control to a lower controller, until complexity is small enough to control, sometimes this works like MVC. But lots of times, this complexity is still hard to manage. Very often, Model, View, Controller still creates conflict, controller is still a bottleneck of communications.

hm.js

About three years ago, I was thinking whether it's possible to get rid of controller completely, so I developed a JavaScript library hm.js, I call it Model-View-Subscription library. The following is an implementation in jsbin using hm.js. The following is the view.

<div>You've clicked <span id="lblCount"></span> time
  <span id="lblPlural">s</span></div>

 <button id="btnClick" >Click me</button>

 <div id="divWarning">
  That's too many clicks! Please stop before you wear out your fingers.
  <button id="btnReset">Reset clicks</button>
 </div>

Here is the model

hm( "clickApp", {
  clickCount: 0, 
  overClicked: function() { 
    return this.get( "clickCount" ) >= 3; 
  }, 
  plural: function() { 
    return this.get( "clickCount" ) > 1; 
  } 
} );

Here are the subscriptions

$(function () {
  
  var model = hm("clickApp");
  
  //model subscribe view, handler change the subscriber
  model.cd("clickCount").sub($("#btnClick"), "click", function (e) {
      this.set(this.get() + 1);
  });
  
  //view subscribe model, handler change subscriber
  $("#btnClick").sub(model.cd("overClicked"), "afterUpdate", function (e) {    
    this.attr("disabled", e.publisher.get());
  });
  
  //view subscribe model, handler change subscriber
  $("#lblCount").sub(model.cd("clickCount"), "init afterUpdate", function (e) {
    this.text(e.publisher.get());
  });
  
  //view subscribe model, handler change subscriber
  $("#lblPlural").sub(model.cd("plural"), "init afterUpdate", function (e) {
    
    this[e.publisher.get() ? "show" : "hide"]();
  });
  
  //view subscribe model, handler change subscriber
  $("#divWarning").sub(model.cd("overClicked"), "init afterUpdate", function (e) {
    
     this[e.publisher.get() ? "show" : "hide"]();
  });
  
  //model subscribe view, handler change subscribe
  model.cd("clickCount").sub($("#btnReset"), "click", function () {
     this.set(0);
  });
  
});

The code may be a bit long, but it is actually very straightforward. When I wrote the above code, I was thinking from the perspective of subscribers, where I have not desire to control others, I just want to control myself. Unlike normal event handling, all subscription has explicit publisher and subscriber. Unlike normal event handler, subscription handlers all update the subscriber but never update the publisher or any other object. Also inside of the handler, there is no hard reference to DOM or model, this make the handler very portable. Because of the loose coupling between model and view, the library can handle a very complicated view. The library also supports declarative subscription. The implementation of declarative subscription is in JSBIN. And you can remove the above subscription code.

 <div>You've clicked <span text='clickCount'></span> time<span
  show="clickCount|>1">s</span></div>
 <button ++='clickCount' disable='overClicked'>Click me</button>
 <div show="overClicked">
  That's too many clicks! Please stop before you wear out your fingers.
  <button 0="clickCount">Reset clicks</button>
 </div>

AngularJs

AngularJs is the most popular Single Page Application framework nowadays. But some people complain that the learning curve is deep. But if you appreciate the benefit of subscription, you can easily avoid the pitfall and adopt the best practice.

People call AngularJs a MVC framework, I don't know why. Is it because it has a component call controller? If you have enough experience in using Angular, you will find that controller actually does not control anything. It is just a place you write code to expose model to views and directives via an object called scope. I don't know why Angular call it controller, maybe they are running out of good name, or maybe they want to stick with popular name "controller". I would rather call it "model exposer". The model is purely Plain old JavaScript Object (POJO), it does not contain any view related code. The interaction between view and model is through subscriptions, which is created in directives. In the following demo implemented using Angular, I don't use any built-in directive "ng-xxx" and use custom directive in order to illustrate this subscription concepts in AngularJs.

Here is the model exposed by controller.

var app = angular.module("myApp", []);
  
  app.controller("modelExposer", function ($scope) {
    angular.extend($scope, {
      clickCount: 0,
      overClicked: function () {
        return this.clickCount >= 3;
      },
      plural: function () {
        return this.clickCount > 1;
      }      
    });
  });

Here are the directives, which create the subscriptions between model and view.

app.directive("myClick", function () {
    return function (scope, $elem, attrs) {
      var expression = attrs.myClick;      
    
      
      /*
      model subscribe view, handler change subscriber only
      the pseudo code that I want to write is 
      
      scope.subscribe($elem, "click", function () {
        this.$eval(expression)
       });
       
       */
      $elem.click(function () {
        scope.$apply(function () {
          scope.$eval(expression);
        });
      });      
    };    
  });
  
  app.directive("myText", function () {    
    return function (scope, $elem, attrs) {      
      /*
      view subscribe model, handler change subscriber
       the pseudo code that I want to write is 
      
      $elem.subscribe(scope, attrs.myText, "change", function (value) {
        this.text(value)
       });
       
      */
      scope.$watch(attrs.myText, function (value) {
        $elem.text(value);
      });      
    };
  });
  

  app.directive("myShow", function () {
    return function (scope, $elem, attrs) {      
         /*
      view subscribe model, handler change subscriber
       the pseudo code that I want to write is 
      
    $elem.subscribe(scope, attrs.myShow, "change", function (value) {
        this[value ? "show" : "hide"]();
       });
       
      */
        scope.$watch(attrs.myShow, function (value) {          
          $elem[value ? "show" : "hide"]();      
        });   
    };    
  });
  
  app.directive("myDisabled", function () {
    
    return function (scope, $elem, attrs) {      
      /*
      view subscribe model, handler change subscriber
       the pseudo code that I want to write is 
      
 $elem.subscribe(scope, attrs.myDisabled, "change", function (value) {
        this[value ? "show" : "hide"]();
       });
       
      */
      scope.$watch(attrs.myDisabled, function (value) {
        $elem.attr("disabled", value);
      });    
    };
    
  });

Here is the view, which is decorated with the directives above.

<div ng-app="myApp" ng-controller="modelExposer">

 <div>You've clicked <span my-text="clickCount"></span> time
  <span my-show="plural()">s</span></div>

 <button my-click="clickCount = clickCount + 1" 
     my-disabled="overClicked()">Click me</button>

 <div my-show="overClicked()">
  That's too many clicks! Please stop before you wear out your fingers.
  <button my-click="clickCount = 0">Reset clicks</button>
 </div>
</div>

AngularJs does not mention that view and model are connected by subscriptions, it uses traditional event handling. Neither does it explicitly suggest that the handler should only change subscriber, because there is no explicit subscriber in event handling. So I have put some pseudo code in the comment of directives. The pseudo code is the subscription code that I want to write, but AngularJs does not support them. However, Misko Hevery, the father of AngularJs does understand that subscription is good. He gave a talk of AngularJS MTV Meetup: Best Practices, he mentioned that

  • Treat the scope as read-only in views
  • Treat the scope as write-only in controllers

If you don't have the subscription concept, it may confuse you. But once you understand the subscription concept as shown above, it is very easy to understand. Let's modify it a little bit.

  • Treat the scope as read-only in handler where view subscribes model
  • Treat the scope as write-only in handler where controller (model) subscribes view

What this means is that, when view subscribes scope (exposing model) change event, the handler should not change model, so it is read-only (it should change view). When model subscribes view event, handler should change model, so it is write-only (it should not change view).

In summary, subscription is good, because it forces you to think from the perspective of subscriber, and you tend to write handlers which only affect subscribers and don't control on others. And we can live without controller.

May 4, 2014

service in angularjs

AngularJs is different from other JavaScript client-side framework in that it use dependency injection to manage its components. Although dependency injection is not a new method, in fact it has been very successful for many years, it is a new approach in JavaScript client-side framework. So if you never use dependency injection in other language before, it is pretty confusing. The following is my notes on this topic.

There are basically two step to develop your angularjs application.

  1. package and register your components using module like the following.

    (function () {
      var module = angular.module("mymodule", ["ng"]);
      module.value("user", { firstName: "Johe", lastName: "Doe" };
      module.directive("userWidget",  function (user) {
          //user is injected here.
          return {};
      });
    })();
    
  2. Let angularjs run the show by using an injector inject the components you created.

    <body ng-app="mymodule">
      <user-widget></user-widget>
    </body>
    

In the first step, when the page is loaded, angualar bootstrap the application. In the process of bootstraping application, one important object called "injector" is created which is shared across the application. Normally your don't need to access the injector programatically, or manually create an injector by yourself, so you may have never heard about it, or you might think that module and injector are the same thing. But they are not. In fact, you can create multiple injectors, each of them use different modules. But in the following exercise, I will manually create one, because I want to know internals of module and injector.

For now, there are 5 kinds of components you write in angularjs, service, animation, filter, directive, controller. Anything which is not animation, filter, directive, or controller, is service. If the name service confuse you, you can call service as injectable. It can be anything like a string, a number, an object, a dom element or whatever. An "injectable" is not injected by module, but injected by a injector, which has information from modules. The following code create an injector.

var modules = ["ng"];
var injector = angular.injector(modules);

The services we created using module is not really service instance, but service provider. During the creation of injector, angularjs import the service provider we created. However the instance of service is not automatically created. In the following, I have modified angularjs's source code to expose the cached service providers in injector as injector._providerCache and expose the cached service instance as injector._instanceCache, in the following screen shot we can confirm this.

When the injector is asked for an component instance, the injector will firstly check whether the component instance is in cache, if it is true, then return it , if not, ask the corresponding component provider to create an instance, cache the instance, and return it like the following.

AngularJs allows your to create your service provider in several ways. module.provider() is the most flexible way among them. The provider passed into the method need be an object with "$get" method which return to the service.

module.provider()

var module = angular.module("module", []);
module.provider("greeter", function () {
  return {
    greeting: "hello",
    $get: function () {
      //here this refer to the service provider
      var greeting = this.greeting;
      return function (name) {
        console.log(greeting + "," + name);
      };
    }
  };
});
var injector = angular.injector(["module"]);
var greeter = injector.get("greeter");
greeter("Fred"); //output hello,Fred

The flexibility of module.provider() is that you customize customize it later. Let's say, the "greeter" provider is created by a third party company. And you want to customize it's behavior before it get injected. You can write the following code.

var mymodule = angular.module("mymodule", ["module"]);

mymodule.config(function (greeterProvider) {
  greeterProvider.greeting = "hi";
});

var injector = angular.injector(["mymodule"]);
var greeter = injector.get("greeter");
greeter("Fred"); //output hi,Fred

module.factory()

If you don't need such flexibility of service provider, you can use module.factory() method, which is a simplified version of module.provider() method.

var module = angular.module("module", []);
module.factory("greeter", function () {
  return function (name) {
    console.log("hello," + name);
  }
});

var injector = angular.injector(["module"]);
var greeter = injector.get("greeter");
greeter("Fred");

Behind the scene, the module.factory() still create service provider internally exactly like created by the module.provider(), the result of the following is identical to the result of above code.

module.provider("greeter", function () {
  return {
    $get: function () {
      return function (name) {
        console.log("hello," + name);
      };
    }
  };
});

module.service() -- don't use

AngularJs also has a module.service() method which is very similar to module.factory(). In fact, in the above example, you can replace the module.factory() method with module.service(), the final result is the same (but the calling method is different), like the following.

module.service("greeter", function () {
  return function (name) {
    console.log("hello," + name);
  }
});

So why do we need a service method? How is the difference between this two. The source code angularjs show that the service method internally call factory method like the following.

function service(name, constructor) {
  return factory(name, ['$injector', function ($injector) {
    return $injector.instantiate(constructor);
  }]);
} 

This means that the factory method can do all the thing that that service method can do. The difference is that provider function is treated as constructor, it is called like "new constructor()". The following shows the difference

module.service("user", function () {
  this.firstName = "John";
  this.lastName = "Doe";
});

module.factory("user", function () {
  return {
     firstName: "John",
     lastName: "Doe"
  };
});

So when should we use service method, when should we use factory method. So far I never encounter a case when I have to use service method, and factory method is not able to do so. So my opinion is that, never use "service" method, always use "factory" method, because "factory" method simpler and more capable.

module.value()

If you look at the factory method, the "$get" member of real provider is a function which return a instance of the provider. Why can't the "$get" member be just the instance itself? Ok, angulajs has another method "module.value()" which try to meed this need. The value method simply return the instance like the following.

module.value("greeter", funnction (name) {
  console.log("hello," + name);
});

module.value("user", {
 firstName: "John",
 lastName: "Doe"
});

However, internally, the value method is like the following

function value( name, val ) {
 return factory( name, function() {
   return val;
 });
}

So the value method still convert the value into a provider which provide the value internally. But the question, "Why can't the "$get" member be just the instance itself instead of a function which provide the value?" is still not answered. What is the benefit of doing that. Let's look at the following code.

module.value("user", {
 firstName: "John",
 lastName: "Doe"
});

module.factory("greeter", function (user) {
  return function () {
   console.log("hello," + user.firstName + "," + user.lastName;
  };
});

In the above code, the greeter depends on user, the user is passed in the factory method by the injector. If the "$get" is the instance, but not a function, the "user" dependency will not be able to injected. However, if your instance does not have external dependencies which need to be injected by injector, you should use "value" method, which is more expressive, otherwise use "factory" method instead.

module.constant()

All the method above create service provider, which can return a service instance. module.constant() is different in that it does not create service provider, but it create the service instance directly. What this means is that it cannot be configurable using module.config(fn). Before you use injector.get(constantKey) to get the instance, it is already created and cached, like the following.

module.config(fn)

AngularJs has one more method module.config(fn) allow you config imported service provider. When an injector is being created, all the service providers created by the module.provider(), module.factory(), module.service(), module.value() is imported first using $provide. Then the config functions will run. The $provide dependencies can also be injected into the functions, the service providers created can also be injected into the functions. For example, if you create a service call "greeter", the "greeterProvider" can be injected into the config functions, but not the "greeter", because at this stage you are about to customize "greeterProvider" to create "greeter", that is why "greeter" can not be injected. This has been shown in previous demo

Also module.config allow you to create service provider using $provide object. The $provide object has the following method

$provide.provider(key, value); 
$provide.factory(key, value);
$provide.service(key, value);
$provide.value(key, value);
$provide.constant(key, value);

$provide.decorator(key, value);

AngularJs use the first 5 methods to import the service provider created using module method. For example, $provide.provider(key, value) is used to import the provider created by module.provider(key, value), so far and so on. But the question is why we want to use $provide in config function to create service provider directly instead of using the method of module, as they looks like do the same thing? In fact, in AngularJs use the config method the directly create service provider, like the following, but not using module methods.

var ng = angular.module("ng", []);
ng.config(function ($provide) {
$provide.provider({                              
    $anchorScroll: $AnchorScrollProvider,        
    $animate: $AnimateProvider,                  
    $browser: $BrowserProvider,                  
    $cacheFactory: $CacheFactoryProvider,        
    $controller: $ControllerProvider,            
    //..and more 
});                            
});                  

Honestly, I don't have an definite answer. But I think it is different way to organize your code, maybe AngularJs team think that is better for code minification or file organization. But the module method is good enough to organize application level development (vs framework development).

The $provide.decorator() is most interesting method of $provide object. You can use it to extend existing service provider. The following is an example

var module1 = angular.module("module1", []);
module1.value("name", "John");


var module2 = angular.module("module2", ["module1"]);
module2.config(function ($provide) {
  $provide.decorator("name", ["$delegate", function (oldInstance) {
    return oldInstance + "," + "Doe";
  }]);
});


var injector = angular.injector(["module2"]);
injector.get("name"); //name is John,Doe

If you have question about service dependency injection in angular, please leave me a note below.