This is part 2 of our series. Click here if you need to read part 1.
Now that we have our project set up, we can start building our application.
This post contains a number of templates you can use to start hacking away.
Module
/* To ensure other modules your app depends on loads before your app,
 * ensure you have these amd-dependecy special comments at the top.
 * This loads them without actually importing them.
 *
 * Be sure to export your module, so you can register components on it
 * later.
 */
/// <amd-dependency path="ui-router" />
/// <amd-dependency path="ui-bootstrap" />
import {module} from "angular";
export var app: angular.IModule = module("app", [
  "ui-router",
  "ui-bootstrap"
]);
Controller
/* We can use classes as controllers. These classes can also work as
 * controllers for directives.
 */
import {controller, IHttpService, IScope} from "angular";
import {app} from "../app.module";
// If we want things on the $scope, we need to make a custom scope interface
// that extends the default.
IAppScope extends IScope {
  disabled: boolean
}
// export the class so we can import it into our unit tests
export class AppController {
  // To inject dependencies, use the $inject syntax
  public static $inject: Array<string> ["$scope", "$http"];
  // Put whatever you're binding on your views in the public space
  public user: string;
  // Be sure to save references to injected services if you need access to them
  // outside the constructor
  private $http: IHttpService;
  private $scope; IAppScope;
  constructor($scope: IAppScope, $http: IHttpService) {
    $scope.disabled = true;
    this.$scope = $scope;
    this.$http = $http;
    $http.get("http://example.com/myresource").then((data: string) => {
      this.user = data;
      $scope.disabled = true;
    });
  }
}
app.controller("AppController", AppController);
Directive
import {IDirective} from "angular";
import {app} from "../app.module";
app.directive("myDirective", MyDirective.Factory);
// Now we can even extend our directive if we want to inherit from it.
class MyDirective {
  public restrict: string = "E";
  public controller: MyDirectiveController = MyDirectiveController;
  public controllerAs: string = "vm";
  public static Factory(): IDirective {
    return new this();
  }
}
export class MyDirectiveController {
  // ...
}
Service
import {IHttpService} from "angular";
import {app} from "../app.module";
// Make sure to make interfaces of any models you're getting.
export interface IJsonPlaceHolderPost {
  userId: number;
  title: string;
  body: string;
}
// Much like classes, services are new'd up, so we can use regular classes
// Export the service so we can import it into our unit tests later.
export class MyService {
  public static $inject = ["$http"];
  private $http: angular.IHttpService
  constructor($http: angular.IHttpService) {
    this.$http = $http;
  }
  public getPost(id: number): angular.IHttpPromise<IJsonPlaceholderPost> {
    return this.$http.get(`http://jsonplaceholder.typicode.com/posts/${id}`);
  }
}
app.service("myService", MyService);
Factory
import {IWindowService} from "angular";
import {app} from "../app.module";
export interface IUserInfo {
  username: string;
  token: string;
  fullName: string;
}
// This time we use a factory pattern to create the service.
export class MyService {
  public userInfo: IUserInfo;
  constructor(userInfo: IUserInfo) {
    this.userInfo = userInfo;
  }
  public static factory($window: IWindowService) {
    var userInfo: IUserInfo = JSON.parse<IUserInfo>($window.localStorage.userInfo);
    return new this(userInfo);
  }
}
MyService.factory.$inject = ["$window"];
app.factory("myService", MyService.factory);
Provider
The biggest difference here is that we can configure a provider during any
angular config calls, such as injecting an API endpoint.
import {IHttpService, IServiceProvider} from "angular";
import {app} from "../app.module";
export interface IUserInfo {
  username: string;
  token: string;
  fullName: string;
}
export class MyServiceProvider extends IServiceProvider {
  public static endpoint: string;
  constructor() {
    this.$get.$inject = ["$http"];
  }
  public $get($http: IHttpService): MyService {
    return new MyService($http, MyServiceProvider.endpoint);
  }
}
export class MyService {
  private $http: IHttpService;
  private endpoint: string;
  constructor($http: IHttpService, endpoint: string) {
    this.$http = $http;
    this.endpoint = endpoint;
  }
  public getUserInfo(user: string) {
    this.$http.get(`${this.endpoint}/users/${user}`);
  }
}
angular.provider("MyService", MyServiceProvider);