Friday 15 January 2016

Create a angular controller in Typescript

In this post we are going to see how to create a angular js controllers in Typescript, While coding the Angular js we just create the controller function and assign with the controller along with dependency injection. First let we see some simple sample in angular js, next we will see how to create a same kind of thing in Typescript.

var app= angular.module('app',[]);


app.controller('MainController', ['$scope', function ($scope) {
        $scope.name = "Employees";
        $scope.title = "Angular Sample";

        $scope.getEmployees = function () {
            $scope.Employees = [
                { id: 1, name: "Rajesh", address: "Chennai" },
                { id: 2, name: "Suresh", address: "California" },
                { id: 3, name: "Ramu", address: "Pune" },
                { id: 4, name: "Shiny", address: "London" }
            ]
        }

    }]);


Now we see how to create a code in Typescript, In Typescript we have to create everything inside the module, even the creation of angular module must resides in a module pattern, but the important thing is order of execution is very important in Typescript. First here we will create a Controller Module , then assign it in the root module.

Here we have to take care 4 things 
1.  Model , Employee
2. Inject the Scope variable , so we have to create a interface which tells what must resides inside the scope, it must               derive from ng.IScope
3. Implement the scope methods and properties in the controller
4. Assign the controller in the Main Module angular 



module DotnetVisio.Model {
    export class Employee {
        id: number;
        name: string;
        address: string;
    }
}

Above we can see that the Employee model consists of three properties id, name, address. 
The export keyword is used, which makes the Employee model to expose outside the  
DotnetVisio.Model namespace.


module DotnetVisio.Interfaces {
    export interface IMainScope extends ng.IScope {
        name: string;
        title: string;
        Employees: Array<Model.Employee>;
        getEmployees(): void;
    }
}

Here in interface we have to specify the export keyword, which makes the interface to access 
in other module, Next thing is we have to derive the interface from the ng.IScope, then we 
have to declare the properties and methods which are going to expose against this Scope, in 
this example we are declaring 3 properties and 1 method.

module DotnetVisio.Controllers {

    export class MainController{
        private $scope: Interfaces.IMainScope;

        constructor($scope: Interfaces.IMainScope) {
            var ViewModel = this;
            ViewModel.$scope = $scope;
            ViewModel.$scope.title = "Angular Sample";
            ViewModel.$scope.name = "Employees";
            ViewModel.InitMethods();
        }

        private InitMethods(): void {
            var ViewModel = this;

            ViewModel.$scope.Employees = [];

            ViewModel.$scope.getEmployees = function () {

                ViewModel.$scope.Employees =  <Model.Employee[]>[
                    <Model.Employee>{ id: 1, name: "Rajesh", address: "Chennai" },
                    <Model.Employee>{ id: 2, name: "Suresh", address: "California" },
                    <Model.Employee>{ id: 3, name: "Ramu", address: "Pune" },
                    <Model.Employee>{ id: 4, name: "Shiny", address: "London" }
                ];

            }
            
        }
        
        static $inject = ['$scope'];
    }  
}

Above controller creation in Typescript  we are creating a module which  have a class with export, First thing is we must know the what are the things need to be inject in the constructor, so to do that we have to specify the static property named   ,static $inject = ['$scope'] When seeing the scope in we are specifying the type as $scope: Interfaces.IMainScope, then we are setting the scope in Current instance, so we can get it in through out the system, but before doing that we have to set the this instance to a variable  var ViewModel = this;, because the instance present in the constructor are not the same as the child function present inside a function (function inside another function), so this keyword refers to different instance, so to access the main instance due to avoid confusion or collision we are referring it to a variable, Finally assign the values to the $scope variable inside the function with the type reference.


ViewModel.$scope.Employees = <Model.Employee[]>[
                    <Model.Employee>{ id: 1, name: "Rajesh", address: "Chennai" },
                    <Model.Employee>{ id: 2, name: "Suresh", address: "California" },
                    <Model.Employee>{ id: 3, name: "Ramu", address: "Pune" },
                    <Model.Employee>{ id: 4, name: "Shiny", address: "London" }
                ];




Finally we are going to set the controller to the module


module DotnetVisio.Module {

    var app = angular.module('app', []);
    app.controller('MainController', Controllers.MainController);    

}



From this post you can learn how to create a controllers of angular js in Typescript.

Thursday 14 January 2016

Create a Basic Sample Angular JS Application using Typescript

In this post we are going to see how to create a sample angular js application using Typescript, visual studio is a best editor for developing a Typescript applications, because it will compile and gives the intellisense  for the typings.


First we have to create a empty Asp.Net web project in visual studio, then we have to download the Typing file for angular to start the code. angular.d.ts, angular-route.d.ts , 





Now we will see a basic sample in which we have to create a module and a controller with one method. To start with Typescript we need the following files need to be added in our project. Don't consider the reference path , just find the file name from the list.

    <script type="text/javascript" src="scripts/angular.js"></script>
    <script type="text/javascript" src="scripts/angular-route.js"></script>
    <script type="text/javascript" src="scripts/jquery-1.9.1.js"></script>
    <script type="text/javascript" src="scripts/bootstrap.js"></script>
    


Install the Typescript from the following link if not present in visual studio 
https://www.microsoft.com/en-us/download/details.aspx?id=48593

Once finish the download the above typing file , add that in your project.


/// <reference path="../scripts/typings/angularjs/angular.d.ts" />
/// <reference path="../scripts/typings/angularjs/angular-route.d.ts" />

Now create a typescript file app.ts and add the above reference in the first two line to get the intellisense while coding.

We have to do the things in order so first we have to create a model, then interface, then controllers, finally create module.
Get a Employee List is the sample we are currently trying 

Create a Model:
 In Typescript we can define the custom data types in model, then we can refer it in variable type, Now here Employee is the Type, so the sample will be like following.

app.ts
/// <reference path="../scripts/typings/angularjs/angular.d.ts" />
/// <reference path="../scripts/typings/angularjs/angular-route.d.ts" />

module DotnetVisio.Model {

    export class Employee {
        id: number;
        name: string;
        address: string;
    }
}


when you save the file it will generate the Js file, the output file will be.

Generated code in app.js
/// <reference path="../scripts/typings/angularjs/angular.d.ts" />
/// <reference path="../scripts/typings/angularjs/angular-route.d.ts" />
var DotnetVisio;
(function (DotnetVisio) {
    var Model;
    (function (Model) {
        var Employee = (function () {
            function Employee() {
            }
            return Employee;
        })();
        Model.Employee = Employee;
    })(Model = DotnetVisio.Model || (DotnetVisio.Model = {}));
})(DotnetVisio || (DotnetVisio = {}));


Create a Interfaces:
Now we have to create a Interface for Scope and that need to be derived from the ng.scope, because we have to specify or add the things which are need to be there in scope, then we have to specify that scope type in controller. Here in this sample we are going to add the IMainScope which is dervies from ng.IScope , then later we will specify that type in the controller , In sample we are specifying that scope must have the three property and a method.


IMainScope extends ng.IScope


app.ts
module DotnetVisio.Interfaces {
    export interface IMainScope extends ng.IScope {
        name: string;
        title: string;
        Employees: Array<Model.Employee>;
        getEmployees(): void;
    }
}


Create a Controller:
Creating a controller is little bit different from the normal angular js applications, Generally while creating controller we must pass the dependency as a parameters and map the attributes to the scope inside the controller like below.

Normal Angular JS Controller Code:
app.controller('MainController', ['$scope', function ($scope) {
        $scope.name = "Employees";
        $scope.title = "Angular Sample";

        $scope.getEmployees = function () {
            $scope.Employees = [
                { id: 1, name: "Rajesh", address: "Chennai" },
                { id: 2, name: "Suresh", address: "California" },
                { id: 3, name: "Ramu", address: "Pune" },
                { id: 4, name: "Shiny", address: "London" }
            ]
        }

    }]);

Now we will see how to create a equivalent Typescript code, in typescript we have to specify the dependency to inject using the $inject as Static array property or directly write as controller.$inject = [];

app.ts
module DotnetVisio.Controllers {

    export class MainController{
        private $scope: Interfaces.IMainScope;

        constructor($scope: Interfaces.IMainScope) {
            var ViewModel = this;
            ViewModel.$scope = $scope;
            ViewModel.$scope.title = "Angular Sample";
            ViewModel.$scope.name = "Employees";
            ViewModel.InitMethods();
        }

        private InitMethods(): void {
            var ViewModel = this;

            ViewModel.$scope.Employees = [];

            ViewModel.$scope.getEmployees = function () {

                ViewModel.$scope.Employees =  <Model.Employee[]>[
                    <Model.Employee>{ id: 1, name: "Rajesh", address: "Chennai" },
                    <Model.Employee>{ id: 2, name: "Suresh", address: "California" },
                    <Model.Employee>{ id: 3, name: "Ramu", address: "Pune" },
                    <Model.Employee>{ id: 4, name: "Shiny", address: "London" }
                ];

            }
            
        }
        
        static $inject = ['$scope'];
    }  
}

When you see above code we are injecting the $scope in $inject Array property to the controller, it is a static one, it can be declare in two ways one is declare as a static inside the controller or outside the controller function just add a property like MainController.$inject = ['$scope'], another thing here we have to notice is we are assign a this keyword to the variable named ViewModel, this is because the current constructor function instance refers to this, we must add the $scope property to the Controller function instance.so this.$scope is added from the injector , and also we are specifying the type of the scope as IMainScope, which have three properties and a method, after assign the $scope to the instance we have to access it through the instance variable, now there is a question we can use the this keyword instead of doing that why we have to create a another variable and assign the instance to that, because this parameter refers in root function cant be the same of child function. 

For example Here InitMethods() is a function which is used to map the methods in the scope $scope, when we use the this parameter inside the method is not the same as the this parameter used inside the method getEmployees, how means when you try to access the property Employees inside the getEmployees method like below this.$scope.Employees = [], it will show error as undefined, because both the this are refers to two different ones, now we are need the outer scope this, so to access the instance, we are maintain the instance in a variable named ViewModel, then access that inside the getEmployees() method will able to access everything in $scope like Employees Property.


Generated code in app.js
var DotnetVisio;
(function (DotnetVisio) {
    var Controllers;
    (function (Controllers) {
        var MainController = (function () {
            function MainController($scope) {
                var ViewModel = this;
                ViewModel.$scope = $scope;
                ViewModel.$scope.title = "Angular Sample";
                ViewModel.$scope.name = "Employees";
                ViewModel.InitMethods();
            }
            MainController.prototype.InitMethods = function () {
                var ViewModel = this;
                ViewModel.$scope.Employees = [];
                ViewModel.$scope.getEmployees = function () {
                    ViewModel.$scope.Employees = [
                        { id: 1, name: "Rajesh", address: "Chennai" },
                        { id: 2, name: "Suresh", address: "California" },
                        { id: 3, name: "Ramu", address: "Pune" },
                        { id: 4, name: "Shiny", address: "London" }
                    ];
                };
            };
            MainController.$inject = ['$scope'];
            return MainController;
        })();
        Controllers.MainController = MainController;
    })(Controllers = DotnetVisio.Controllers || (DotnetVisio.Controllers = {}));
})(DotnetVisio || (DotnetVisio = {}));


Create a Module:
Module must be created inside a module pattern like below and refers the controller with name and refers the function as second parameter

app.ts
module DotnetVisio.Module {

    var app = angular.module('app', []);
    app.controller('MainController', Controllers.MainController);    

}

Generated code in app.js
var DotnetVisio;
(function (DotnetVisio) {
    var Module;
    (function (Module) {
        var app = angular.module('app', []);
        app.controller('MainController', DotnetVisio.Controllers.MainController);
    })(Module = DotnetVisio.Module || (DotnetVisio.Module = {}));
})(DotnetVisio || (DotnetVisio = {}));


Html :
Now in html we have to refers all the JS files, including the app.js, because we are not referencing the app.ts file in HTML, because the Typescript  compiler converts the code in to java script, we have to refer that file 

In this sample i am using the Bootstrap also for a good looking UI. Here in this html there is no change  as usual we can declare the app module and controller . Variable can be accessed using the $scope map with the tag

<!DOCTYPE html>
<html>
<head>
    <title></title>
	<meta charset="utf-8" />
    <link rel="stylesheet" href="Content/bootstrap-theme.css" type="text/css" />
    <link rel="stylesheet" href="Content/bootstrap.css" type="text/css" />

    <script type="text/javascript" src="scripts/angular.js"></script>
    <script type="text/javascript" src="scripts/angular-route.js"></script>
    <script type="text/javascript" src="scripts/jquery-1.9.1.js"></script>
    <script type="text/javascript" src="scripts/bootstrap.js"></script>
    <script type="text/javascript" src="app/app.js"></script>

</head>
<body ng-app="app">

    <div class="row" style="padding:20px"></div>
    <div class="row">
        <div class="col-lg-2"></div>
        <div ng-controller="MainController" class="panel panel-info col-lg-4">
            <div class="panel-heading">
                {{title}}
            </div>
            <div class="breadcrumb">{{name}}</div>
            <div class="panel-body">
                <div class="row">
                    <div class="col-lg-8"></div>
                    <div class="col-lg-3">
                        <input value="Get Employees" type="button" 
                               class="btn btn-primary" 
                               ng-click="getEmployees()" />
                    </div>
                </div>
                <div class="row" style="margin-top:10px">
                    <ul class="list-group">
                        <li class="list-group-item list-group-item-info" 
                            ng-repeat="emp in Employees">
                            <div class="text-center text-muted row">
                                <span class="col-md-3">{{emp.id}}</span>  
                                <span class="col-md-5">{{emp.name}}</span>
                                <span class="col-md-4">{{emp.address}}</span>
                            </div>
                        </li>
                    </ul>
                </div>
                </div>
        </div>
    </div>
</body>
</html>

Full Source Code app.ts (Typescript)

/// <reference path="../scripts/typings/angularjs/angular.d.ts" />
/// <reference path="../scripts/typings/angularjs/angular-route.d.ts" />

module DotnetVisio.Model {
    export class Employee {
        id: number;
        name: string;
        address: string;
    }
}

module DotnetVisio.Interfaces {
    export interface IMainScope extends ng.IScope {
        name: string;
        title: string;
        Employees: Array<Model.Employee>;
        getEmployees(): void;
    }
}

module DotnetVisio.Controllers {

    export class MainController{
        private $scope: Interfaces.IMainScope;

        constructor($scope: Interfaces.IMainScope) {
            var ViewModel = this;
            ViewModel.$scope = $scope;
            ViewModel.$scope.title = "Angular Sample";
            ViewModel.$scope.name = "Employees";
            ViewModel.InitMethods();
        }

        private InitMethods(): void {
            var ViewModel = this;

            ViewModel.$scope.Employees = [];

            ViewModel.$scope.getEmployees = function () {

                ViewModel.$scope.Employees =  <Model.Employee[]>[
                    <Model.Employee>{ id: 1, name: "Rajesh", address: "Chennai" },
                    <Model.Employee>{ id: 2, name: "Suresh", address: "California" },
                    <Model.Employee>{ id: 3, name: "Ramu", address: "Pune" },
                    <Model.Employee>{ id: 4, name: "Shiny", address: "London" }
                ];

            }
            
        }
        
        static $inject = ['$scope'];
    }  
}

module DotnetVisio.Module {

    var app = angular.module('app', []);
    app.controller('MainController', Controllers.MainController);    

}



Full source code generated by Typescript as app.js
/// <reference path="../scripts/typings/angularjs/angular.d.ts" />
/// <reference path="../scripts/typings/angularjs/angular-route.d.ts" />
var DotnetVisio;
(function (DotnetVisio) {
    var Model;
    (function (Model) {
        var Employee = (function () {
            function Employee() {
            }
            return Employee;
        })();
        Model.Employee = Employee;
    })(Model = DotnetVisio.Model || (DotnetVisio.Model = {}));
})(DotnetVisio || (DotnetVisio = {}));
var DotnetVisio;
(function (DotnetVisio) {
    var Controllers;
    (function (Controllers) {
        var MainController = (function () {
            function MainController($scope) {
                var ViewModel = this;
                ViewModel.$scope = $scope;
                ViewModel.$scope.title = "Angular Sample";
                ViewModel.$scope.name = "Employees";
                ViewModel.InitMethods();
            }
            MainController.prototype.InitMethods = function () {
                var ViewModel = this;
                ViewModel.$scope.Employees = [];
                ViewModel.$scope.getEmployees = function () {
                    ViewModel.$scope.Employees = [
                        { id: 1, name: "Rajesh", address: "Chennai" },
                        { id: 2, name: "Suresh", address: "California" },
                        { id: 3, name: "Ramu", address: "Pune" },
                        { id: 4, name: "Shiny", address: "London" }
                    ];
                };
            };
            MainController.$inject = ['$scope'];
            return MainController;
        })();
        Controllers.MainController = MainController;
    })(Controllers = DotnetVisio.Controllers || (DotnetVisio.Controllers = {}));
})(DotnetVisio || (DotnetVisio = {}));
var DotnetVisio;
(function (DotnetVisio) {
    var Module;
    (function (Module) {
        var app = angular.module('app', []);
        app.controller('MainController', DotnetVisio.Controllers.MainController);
    })(Module = DotnetVisio.Module || (DotnetVisio.Module = {}));
})(DotnetVisio || (DotnetVisio = {}));



Output:








From this post you can see how to create a angular js applications using the Typescript. along with creation of module, controller in typescript