Showing posts with label TypeScript. Show all posts
Showing posts with label TypeScript. Show all posts

Tuesday, January 31, 2017

Serverless JoymonOnline.in - Intermediate update & experience

The Serverless is the new buzzword and it is getting really good attention. It is nothing but an architectural style where developers don't need to worry about servers for deployment, scaling etc... Just write and push the code. It will scale automatically.

In the previous article about Serveless, I had mentioned I am in the process of converting my personal site to Serverless. The decision was purely financial. Why should I give money to GoDaddy for hosting some pages which can be served by GitHub pages for free?

This is just an intermediate update about that effort.

Steps

Below are the steps taken during this effort. It may vary from project to project based on complexity. JoymonOnline.in is just a profile site which don't use any custom modules or handlers.
  1. Avoid server side data rendering
    1. Replace .Net third parties with equivalent JavaScript API
    2. Convert each .aspx page to contain its own Angular application.
    3. Avoid ASP.Net specific skin files and use pure CSS
  2. Client side integration
    1. Replace ASP.Net master page with Angular routing.
    2. Bundling, Minification, CI & CD
  3. Backward compatibility
    1. Links
    2. SEO
Please note that these steps are relevant if the decision is 
  • Not to start a fresh app
  • To ensure that the code base is ready to delivery at any point in time.
If business can keep quite during the migration or the development can be done is separate branch ad later merge, these steps are not required. Just start a new app.

Avoid server side HTML rendering

The current www.JoymonOnline.in site uses ASP.Net web forms technology. In other words it uses server side HTML generation and sends it to the browser. There is no rule that Serverless should not use server side rendering. It can use, provided the server side rendering can scale automatically without doing any extra task. For example a WebAPI service end point can return HTML and it can be rendered at browser with the help of JavaScript. That introduce some kind of client side HTML manipulation. Once we take that decision, there is not much differences between rendering full contents at client side v/s rendering some contents at server and inject it to client side views. So in short Serverless goes hand in hand with client side web apps which we generally call SPA (Single Page application). It can't be done in one step. So sub tasks are as follows.

Replace .Net third party with JS API

If we want to replace the third party .Net API with JS equivalent there are 2 options
  1. Use equivalent JS library
    1. Has to make sure the critical API keys are not exposed. Can do client site authentication or be happy with free quota.
  2. Write a FaaS which uses same .Net API and let it return required data to client.
    1. We have to make sure it is secured and key present only at service and service can only be called from our app.
Coming back to JoymonOnline.in, it uses some third party APIs at server side to get data and render  via ASP.Net. GitHub API, Blogger API are the main third parties. So these calls needs to be done from client machine. For GitHub, it was easy as there is straight JS library. But for Blogger it was little difficult as the Google feed API is discontinued. Finally it worked with blogspot feed url.

But for GitHub, there is a limitation due to the quota for unauthenticated API calls. Since the developer key cannot be exposed to client, it allows only 60 requests / hour / IP address. Since JoymonOnline.in is expecting more than 60 calls from single API it is ok to go with quota. 

Convert each .aspx page to contain its own Angular application

Next step is to convert page by page to Angular. This is to make sure that the application is always in functional condition than like a demolished house before renovation. Convert individual pages to its own angular app and render that app inside the ASPX pages. Let that page be just an angular app host. Noting else. 
In this step we have to identify equivalent third party ASP.Net UI controls, if applicable. For example how to replace Telerik web forms controls with KendoUI.

In case the plan is to first get to ng1 and later to ng2, I would strongly recommend to go with components rather than directives. TypeScript is becoming defacto standard for angular. Use that to avoid debugging time. After this step, we will have ASP.Net application but the functionality working from browser via angular.

Avoid ASP.Net specific skin files and use pure CSS

Next thing to tackle are the styles. If the application is using skin files, we have to get equivalent CSS files. Sometimes we may need to do this along with the previous step. Depends on nature of third parties and our code.

Client side integration

The next big step is to integrate things at client side.

Replace ASP.Net master page with Angular routing.

The main pending thing is to have angular master page and routing. We already have separate components in different apps. Just create new app in index.html and have the routing to load proper components. This steps sound simple but it has many things to do.

Bundling, minification, CI, CD etc...

Now its the time to optimize the site and do integration to build pipeline. Till this point, the expectation is that we are able to use existing build system. Recommended is Webpack for client side activities such as compilation and bundling. CD is always confusing with Continuous Delivery and Continuous Deployment. At least make sure it is Continuous Delivery.

Current, JoymonOnline.in using AppVeyor for CI & CD. Though AppVeyor is mainly intended for Windows development, it supports NodeJS as well. So decided to continue in AppVeyor. At this point the build output will be pushed to \docs folder as staging. GitHub pages recently started supporting serving web pages from \docs folder instead of gh-pages branch.

It is not fun to develop JS based client side app using Visual Studio solution file. After this step we don't need .sln file to work with. Node rules the client side web development world. At some point we have to introduce Node. So why not from the start if it is possible to live with only Node? When it is said 'start', it means the starting of the migrated application. If anyone feels they can live with .sln file without Node, let them continue. But better don't use mix. Comparing Node with .sln is not the right comparison. But the intention is to use Node and its ecosystem such as NPM & package,json etc... 

Backward compatibility

These may be optional depends on scenarios.

Links

This will make sure that the bookmarks saved by users are still valid. The old ASP.Net application could have modified to redirect the .aspx pages to new URLs. But for JoymonOnline.in, this is not done.

SEO

The SEO efforts needs to be put if the application is public facing.

These steps itself needs explanations which will be having contents enough for separate post. At this point, the entire application has converted and available at joymon.github.io . The main pending thing is to change settings in GoDaddy to point JoymonOnline.in records to joymon.github.io.

Tuesday, January 10, 2017

My JavaScript Module experiments

Background

After I wrote my post about the selecting Angular 1 for my personal site when Angular 2 is out, I seriously started thinking about myself. Am I too joining the group who hate changes? As mentioned in that post, the main bottleneck is not the concept or syntax of ng2 nor it's performance and stability. The problem was around tools. What are those tools doing? They help us to write modularized JavaScript. They do transpilation, bundling, minification etc...

If we download standard ng2 project starter template, we will get pretty much a good running starter. The tools will be already configured. From there we can simply add our own functionalities. Unless we have crazy requirements, that configuration will work. We just need to add features. Then what is the trouble? The trouble, at least I had was that I am not getting how those tools are doing the magic. I checked with some other people who has problems with ng2. I could see they also have trouble understanding the tool chain. Its very difficult to move ahead in that magic setup especially, if we are coming from little old school who want to know exactly how the software works. For most of the newbies, it doesn't matter. As far as the setup/tool chain is working they can code new features.

Is there a way to survive in web development without knowing bundling? The answer is 'no' as that is the way forward to build huge apps.

So what is the solution. Learn the JavaScript module system from basics with simple samples than  starters which are configured to use features such as transpilation, source map, minification, unit testing, dev & prod  modes etc...

This post explains how I learned module system in my way, though there are tons of tutorials explaining the JavaScript module system. Most of the steps will be pointing to external sites to avoid duplicate content and of course they explain better than me.

What is JavaScript module system

If we have background in Java, it is the equivalent of Java package system. For .Net people, it can be compared to assemblies. Simple as that. But since the JavaScript engines don't have native support for modules, we have to rely on different tools which does the module implementation. To me its like workaround till the browsers or the JS engines know what is module. May be at least in the case of module loading. I am not expecting any JS execution environment will ever help us to create a bundle.

What is the relation to Angular 2 and these module system? Angular 2 uses these module concept and it is good to follow the same for our app as well. So if we download any Angular 2 sample or starter, we can see it uses SystemJS or Webpack. As mentioned earlier, either we can just download a starter and extend it without knowing how the magic works or learn what is the module system from the scratch.

Selecting WebPack

If we google for JavaScript module tools we will see many. Browserify, RequireJS, SystemJS, webpack to name few. We can debate which one is better for days and that itself require one separate post. So for the time being selecting webpack as it is selected by Angular-cli and at least it is not in beta.

NodeJS n NPM are everywhere

It is very difficult now a days to do web development without knowing node and its package management tool NPM. Though Node & NPM doesn't have any role inside browser they are used in tooling side. Webpack also comes as NPM package. So this post assumes reader has knowledge about NodeJS & NPM 

Step 1 Understand via simple ECMA 5

The first thing as JS developer unless we are born to ES6 is to learn how we can modularize ECMA5 or ES5 or simply the traditional JavaScript code. There is no need to write one more tutorial to understand how ES5 can leverage webpack. Just go to 'getting started' tutorial of webpack and try it.

Please try till Section "THE FIRST  LOADER" in the below 'getting started' link.

http://webpack.github.io/docs/tutorials/getting-started/

Before using loader, it is good to know something else. Obviously we should come back to loaders. Because loaders does magic. 

After trying the above, remove the .js extension from require and run. Sample below.

var content = require("./content.js");
to 
var content = require("./content");

We can see still it is working. The file extension is something optional.

Step 2 - webpack.config.js

If we go through any webpack tutorial, we can understand that most of the issues using webpack is because of wrong webpack.config.js. So it is important.

Minimum config

Lets see what is the minimum config required for this webpack.config.js file. Have a look at the below link starting from "Defining a config file" section where it is explained clearly. Read till the "Webpack loaders and preloaders".

Watch mode

This is a useful mode in development. This is explained in the above tutorial.

Dev Server & hot reload

These are again development time features where we can start a light web server which monitors the development changes and reloads for us. This save good amount of time in switching to command window and typing commands. Yet to see what will happen on performance, if there are 100s of files.

The feature is explained in the above tutorial.

Step 3 - Enter TypeScript

A big no to ES6 at this point only because it lacks compile time type system. This is again debatable. If we are dealing with small applications, it is better to be dynamic typed ie pure JavaScript. But for bigger apps, type checking is must. Otherwise it will take a good amount of time  ie time needed for finding out what are the members of objects and what a function accepts and returns.

In this section we are going to see how TypeScript and webpack works together.

The below article below explains TypeScript and how to use TypeScrpt with Webpack. Read from beginning till "Watch Support"
http://www.jbrantly.com/typescript-and-webpack/

Why till "Watch Support". Because it then includes jQuery. Our focus is to understand how webpack can be used to process TypeScript not with jQuery.

Now its time to clone my webpack repo given below. This will be used going forward in this post.
https://github.com/joymon/webpack-starters

It has a folder named ECMA5-TypeScript. Point command line to that folder and run webpack command. We could see it transpiles the logger.ts & tscomponent.ts and output bundle.js along with other ES5 modules. Running the index.html from disk will show some log statements.

"TypeScript Worked !!! - logger module loaded" - Means a ES5 module was able to load TS module.
"TS component which has dependency on JS component worked" - Hope it is self explanatory

Lets see how it worked

Loaders in webpack - ts-loader

Loaders help to process the file, if those are in different formats. For example, today browsers don't know how to read and execute the TypeScript. So the TypeScript needs to be transpiled to JavaScript. That can be done by using the webpack loader mechanism. In this "webpack-starters" repo, ts-loader is used for that purpose. The configuration is present in the webpack.config.js.

After loader does its job, the final bundle.js is created as usual. index.html only knows bundle.js.

TypeScript loading ES5 modules

If we need ES5 code to load a TS module it is easy. Since ES5 don't care about types, we can write any valid js and at runtime only it checks the objects. But if we want to use ES5 module in TS, the first thing is to tell, what is require() function. TypeScript as language don't know what is require(). So to tell TypeScript about require() we have to use nodejs typing. Node typing has the definition for require(). 

To add Node typing the sample is using a package called  @types/node. Refer package.json. 

Please note since this post is not aiming at teaching TypeScript language and what are typing files,  more details on @types/node are omitted.

Step 4 - TypeScript with AngularJS 1.x

Here we are going to next step of using AngularJS 1.x via webpack module mechanism. The sample is present in the TypeScript-Angular1 folder of the "webpack-starters" repo mentioned above. Sample just shows a simple Angular 1 application with one component.

Setting up ng1+TS+webpack from scratch involves multiple steps which are given below
  1. Initial setup of TypeScript+webpack
  2. Include the NPM package for Angular
  3. Include the @types/angular.
  4. A module where angular.module() is called to setup angular. In the sample refer to ngModule.ts
  5. An entry point(bootstrap.ts) module where we can call the above module and add other Angular constructs such as components, services, filters etc...Big sorry for directives for easy conversion to ng2.
  6. Index.html to use required Angular directives.Minimum ng-app.
  7. While adding components export them
Now have a look at the TypeScript-Angular1 folder of the "webpack-starters" if not done already. Below are some questions which might have popped up. The answers are also given along with questions,
  • Why ngmodule.ts? 
    • This is just a class for wrapping the original angular object. This gives us a common place for registering the angular object such as registering components, filters, services etc...This is optional. Just make sure the code which is executing angular.module and other registration functions are getting called.
  • Why bootstrap.ts
    • This acts as entry point for the application. It imports all the other modules which contains the app is ngmodule and all the angular constructs. For simplicity the sample only includes a simple component.
  • How did the require("angular") worked? Who exported the angular library for webpack?
    • This is done by the node_modules\angular\index.js .It exports as angular. If we change this we can see the module is not found.
  • Why webpack-dev-server is needed. Can't we double click and run from the disk?
    • For just ng-app to work, there is no need of web server. But for angular to locate and load the html template, it requires app to be served via url not just from disk. We can even use IIS to serve the folder. Only requirement is to navigate via http protocol.
Any new questions can be asked in the comments which will be included into the post later with answers?

More

This post shows the tip of iceberg. There are many more things which are required to setup a professional application for development and production. With this basic understanding of module system, learning those will be easy.

Some links are given below which are related to JavaScript modules and bundling

Tuesday, January 3, 2017

TypeScripting AngularJS 1.x - Filters

This post is part of TypeScripting AngularJS 1.x series. Other posts are listed below. The sample code is created using Angular 1.5.9, TypeScript 1.8 & angularjs.TypeScript.DefinitelyTyped 6.5.6. 
  1. TypeScripting AngularJS 1.x - Define module
  2. TypeScripting AngularJS 1.x - Define module - improvements for big enterprise apps Improvement
  3. TypeScripting AngularJS 1.x - Using $http 
  4. TypeScripting AngularJS 1.x - Directives
  5. TypeScripting AngularJS 1.x - Filters

Angular Filters in TypeScript

These are small handy reusable functions which can help us to format the data while displaying without modifying the underlying model. Currency and date formatting are excellent examples. We don't need to keep one more property in the model which holds short date of another date object just for displaying. There are many filters built into Angular and it allows us to create new as well.

Below is a code snippet to create custom Angular filter named. HTMLTagRemover using TypeScript. As the name implies it removes any html tags in the string passed to it. 

export class HTMLTagRemover {
    public static filter(): Function {
        return (text: string): string => { 
            return text ? String(text).replace(/<[^>]+>/gm, '') : '' };
    }
} 
AppModule.getInstance().registerFilter("removeTags", HTMLTagRemover.filter);
It is a simple factory function which returns the actual filter function. The last line registers the filter with Angular application. It requires some prior knowledge related to defining Angular module in TypeScript way to understand how to get the AppModule.getInstance() and how it works.

Below is the code of registerFilter() in the AppModule class
registerFilter(name: string,fun:Function) {
    this.app.filter(name, fun);
}
The app is the real Angular object

Dependency injection 

Without dependency injection Angular is never complete. How can we get the dependencies injected into this filter?
export class HTMLTagRemover {
    static $inject: string[] = ['$sce'];
 
    public static filter($sce: ng.ISCEService): Function {
        return (text: string): string => {
            console.log($sce.trustAsHtml(text));
            return text ? String(text).replace(/<[^>]+>/gm, '') : ''
        };
    }
}
This injects $sce which can be used to sanitize data into our filter. Similar to $sce we can inject our own services too.

Complete code can be found in my personal web site source in Github.

Tuesday, December 27, 2016

TypeScripting AngularJS 1.x - Directives

This post is part of TypeScripting AngularJS 1.x series.Other posts are listed below.

  1. TypeScripting AngularJS 1.x - Define module
  2. TypeScripting AngularJS 1.x - Define module - improvements for big enterprise apps Improvement
  3. TypeScripting AngularJS 1.x - Using $http 
  4. TypeScripting AngularJS 1.x - Directives

Angular Directives using TypeScript

Below is a mechanism to create typed Angular directives using TypeScript.

The main thing is that our directive class needs to implement ng.IDirective. After that we can have the corresponding ng.IDirective members. The advantage here is that we don't need to memorize or google for what are the members required for directive. Its all there in ng.IDirective

export class ProjectsDirective implements ng.IDirective {
    public restrict: string;
    public templateUrl: string;
    public controller: any;
    public controllerAs: string;
    public bindToController: boolean | { [boundProperty: string]: string };
    public scope: boolean | { [boundProperty: string]: string };
    constructor() {
        this.restrict = 'E';
        this.templateUrl = 'JS/app/projects.component.html';
        this.controller = "ProjectsController";
        this.controllerAs = "ctrl";
        this.bindToController = true;
    }
}

Above code snippet is taken directly from my personal web site. The members such as bindToController, controller etc... are optional. This is not enough to get the ProjectsDirective available in our application. For that we have to register it with Angular application.

Code snippet below shows the registration.

AppModule.getInstance().registerDirective("projects", () => {
    return new ProjectsDirective() 
});

It gets the instance of the Angular module and calls the registerDirective function. The object here is  a wrapper over real Angular module object. That function in turn calls the real Angular.directive function.

Dependency injection

The dependencies to the directive can be accepted by the directive factory / creation function. That function then can pass those injected objects to the directive constructor. 

Sample code

The code is from my personal web site and it is in GitHub.
Simply clone the repo and compile using Visual Studio 2015. It uses TypeScript 1.8.

Tuesday, November 8, 2016

TypeScript : Writing first typedefinition file for our JavaScript library

TypeScript doesn't have its own runtime. But it makes the JavaScript coding much easier and maintainable. TypeScript and JavaScript goes hand in hand as every valid JavaScript is valid TypeScript. But what if we already have a JavaScript library and we don't have budget to convert that to TypeScript. Can TypeScript call JavaScript functions inside the library?

A JavaScript Library

Wiki says "A JavaScript library is a library of pre-written JavaScript which allows for easier development of JavaScript-based applications..". Mainly JavaScript libraries expose their functionalities via objects or functions. Below is a JavaScript library to do some math functions.

//Code math opeations
var MathLib = {
    Add: function (n1, n2) { return n1 + n2; },
    Subtract: function (n1, n2) { return n1 - n2; }
}

This can be easily invoked from anywhere in JavaScript as its a global variable.
function btnclick() {
    alert(MathLib.Add(2,3));
}

Entering the TypeScript world

Now lets see how the above library can be used from TypeScript. If we simply copy paste the JavaScript function to call the library, it won't compile. That is because TypeScript don't know what is the type of MathLib object and don't know whether there is a function called Add() is there in that object.

So what to do? If we want to call any JavaScript library we need to make sure its available in TypeScript. That can be done by writing type definitions for JavaScript library.

declare var MathLib: IMathLib;
interface IMathLib{
    Add(n1: number, n2: number);
    Subtract(n1: number, n2: number);
}

Include the above declarations into TypeScript file then we can see it is compiling and producing same JavaScript code.

What magic happened here? We told TypeScript compiler that there is an variable called MathLib and its type is IMathLib. That type has 2 methods and the signature of those methods. We can tell that the arguments are 2 numbers. Now TypeScript passes the compilation assuming that during runtime there would be an valid object in the variable MathLib with 2 functions with proper names.

The interface name can be anything but the function names should be exactly same. the parameter type can be any valid type in TypeScript including the 'any' type.

Virtual TypeSystem of TypeScript

The type system in TypeScript exists only during compilation. During runtime nobody is enforcing types. This is because the runtime is JavaScript and that is not a hard typed system.

What is <filename>.d.ts

d.ts extension is a convention in TypeScript used to group all the TypeDefinitions. So that our application code will never be confused with TypeDefinition files.

Just move the declare var... line to a file named defs.d.ts and include to the project. It will compile. If there are any compilation error make sure your .ts file which consumes the library has a referene to the type definition. Sample code below

/// <reference path="defs.d.ts" />
function btnclick() {
    alert(MathLib.Add(2, 3));
}

Writing TypeDefinitions for third party JavaScript library

The above clearly shows in the TypeScript world the consumer of the library can simply create the type definitions for any JavaScript library. When we want to write type definitions for large libraries better make sure we are creating proper modules so that there is a clear separation. Also use exports properly.  

The type definitions for all most all famous libraries are already available in internet. One of the repository for type definitions is DefinitelyTyped

References

http://peter.grman.at/how-to-write-typescript-definition-files/
http://www.codeproject.com/Articles/528295/ModularizationplusinplusTypeScript

Tuesday, June 7, 2016

TypeScript - Static Constructor

TypeScript doesn't have inbuilt support for static constructor. But when we code applications there will be many scenarios where we need to execute something once for a class. Below is one example we can workaround this in TypeScript
module Company.Application.Feature.SubFeature {
    "use strict";
    export class MyClass {
        private static _constructor:void = (() => {
            var obj: MyClass = new MyClass();
            obj.setup();
        })();
        constructor() {
        }
        setup() {
        }
    }
}

How it works

The _constructor line will be executed as IIFE. ie the parameter less arrow function is executed when the script is loaded and assign void/undefined to _constructor variable.

Difference with .Net static constructor

In .Net the static constructor is kind of lazy.ie it will execute when that class is first referred for object creation or any other static method is called. But this workaround in TypeScript executes the static constructor soon after the script is loaded.


Tuesday, May 31, 2016

Converted HTML5+JavaScript app to TypeScript

Below are me experiences in converting one of my small personal project from HTML,JavaScript to TypeScript.

Converting Karel to TypeScript

The application is simple one screen. Its used for teaching programming basics.

The conversion has mainly 2 steps.

Get the .js to .ts

  1. Create new TypeScript project in Github. Checkout the same in local machine.
  2. Create a new TypeScript project in Visual Studio. Better have Web Essentials installed.
  3. Copy paste the existing JavaScript code.
  4. Rename the .js files to .ts
  5. There may be validation errors on compilation. But it will generate .js files.
  6. Add jQuery map file via nuget 
    1. install-package jquery.TypeScript.DefinitelyTyped -version 2.0.0
  7. Better use Local IIS server setup from Visual Studio
  8. Run the app and make sure it works as usual.
  9. Commit the project.
  10. Host to staging. No need to deploy any .ts files to server.
Some steps are solely related to Github source control repository not at all related to TS. The project is live at https://github.com/joymon/karel-typescript

Use the .ts features

Now leverage TypeScript features one by one. Below are some examples.

world.ts - added class support



https://github.com/joymon/Karel-TypeScript/commit/c4667d3f765e183db9d85938488a760cd526485d?diff=split

TypeScript clearly shows the dead code. Remove everything. Refactor with confidence as it will show errors early.

How to convert from JavaScript to TypeScript is now a solved question. This approach can be used on even large apps. There are chances that somethings may show compilation errors due to lack of type definitions. eg: FileReaderSync class. Ignore those as any valid .js is valid .ts and .ts compiler will produce the code for everything.

Happy conversion.

Tuesday, May 17, 2016

TypeScripting AngularJS 1.x - using $http

This is a continuation of older posts in TypeScripting AngularJS 1.x series. Here lets see, how we can use the $http service in typed way using TypeScript.

The API

The main TypeScript type, we need to understand here, is the ng.IHttpService. This is the equivalent type of $http object. This comes via the AngularJS typedefinition file which can be downloaded from nuget. The another type is the ng.IHttpPromiseCallbackArg<T>. This is the container which is returned via the Then() method.

Sample

Before coding the client side, lets see the server side code which is going to be called from browser.
public class HomeController : Controller
{
    public ActionResult GetCountryMetaData(string id)
    {
        RegionInfo rInfo = new RegionInfo(id);
        return Json(new
        {
            DisplayName = rInfo.DisplayName,
            Currency = rInfo.CurrencyEnglishName,
            CurrencySymbol=rInfo.CurrencySymbol
        },JsonRequestBehavior.AllowGet);
    }
}

This action method takes id as string and return the country / region details. Anonymous return type has 3 properties which are all strings.
If we host this inside IIS using web application named testapi, we can invoke the API by browsing the below url.

http://localhost/testapi/home/getcountrymetadata/nz
Result will be - 
{"DisplayName":"New Zealand","Currency":"New Zealand Dollar","CurrencySymbol":"$"}

Let's see how this can be invoked from TypeScript without using 'Any' type.
export class CountryController {
        testprop: string;
        emp: Country;
        http: ng.IHttpService;
        Countries: Array<Country> = new Array<Country>();
 
        constructor($scope: any,
            $http: ng.IHttpService,
            this.http = $http;
            $scope.Countries = this.Countries;
        }
        getForChina() {
            this.http
                .get('http://localhost/testapi/home/getcountrymetadata/cn')
                .then((result: ng.IHttpPromiseCallbackArg<Country>) => {
                    this.Countries.push(result.data);
                });
        }
}
class Country {
    DisplayName: string;
    Currency: string;
    CurrencySymbol: string;
    constructor() {
 
    }
}

Casting in TypeScript

The first confusion will happen on the casting of http result to Country object. Where we are telling the return type is Country in TypeScript?

Here is the difference between the real type safe languages such as C# / Java and TypeScript. In TypeScript since its finally running as JavaScript, we can accept values in any type, if that looks similar to the incoming object. Here the output of web request has properties which are matching to properties of Country class so those are just copied. If there are no matching properties still this code compiles but at run-time the properties of result object will be undefined. No exception in any case.

We can make it more TypeSafe by adding generic type to the get method.
this.http
    .get<Country>('http://localhost/testapi/home/getcountrymetadata/cn')
    .then((result: ng.IHttpPromiseCallbackArg<Country>) => {
                    this.Countries.push(result.data);
    });

Passing typed parameters to $http.get()

The get() accepts an optional ng.IRequestShortcutConfig object too. Lets see how that can be passed into the method in type safe way.

var config: ng.IRequestShortcutConfig = {};
            config.cache = true;
            this.http
                .get<Country>('http://localhost/testapi/home/getcountrymetadata/cn',config)
                .then((result: ng.IHttpPromiseCallbackArg<Country>) => {
                    this.Countries.push(result.data);
                });

Interesting thing here in TypeScript is, we don't need to create the implementation class to use the interface. This again is feasible, since it runs in JavaScript engine where there is no type safety. After the compilation everything is JavaScript. We know that, there is nothing called interface in JavaScript runtime.

The {} creates an object just like in JavaScript. After that we can set required properties. Since we have declared the variable as ng.IRequestShortcutConfig, we will get intellisense on the config object. We don't need to remember all the properties, which we need to do in pure JavaScript programming.

Here config.cache.= true tells the $http, to cache the requests using Angular JS cache factory.

Happy TypeScripting...

Tuesday, May 10, 2016

TypeScript - Reflection ie create object from its class name in string

Reflection

Reflection is a mechanism to talk to the metadata of classes or other programming constructs in programming language and do things without coding it. For example to listing out all the methods of a class where the class name is in string, invoking a method name by accepting the method name from user. Also creating an object without new keyword etc... Refer what says wiki on reflection for more details.

Creating object by its name not using new

In this post, we are going to see how we can create an object by knowing its name in a string variable. Since the value/name of class can be changed runtime, we cannot use new keyword. If we want we can use a switch construct based on the value in the string and have new in the case blocks. But that will work only when all the possible class names are known in advance. In a plugin model where anyone can add implemented classes at a later point, this switch mechanism will not work.

This is the class, whose object we are going to create.
module Company.App.Module {
    export class Greeter {
        constructor() {
        }
        greet(message: string) {
            return "Hello, " + message;
        }
    }
}
Below is the con
import Greeter = Company.App.Module.Greeter;
var obj: any = ObjectFactory.create("Company.App.Module.Greeter");
var greeter: Greeter = <Greeter>obj;
alert(greeter.greet("Joy"));
Look at the argument to ObjectFactory.create(). Its a string. So the question is how do we write the create() function.

Forbidden,dangerous JavaScript method eval()

For some reason, there are some constructs in programming language which are taught to be dangerous and should not use. eval() is one among that. But in this scenario, we are going to use eval() to do our job easier.
class ObjectFactory {
    static create(className: string) {
        var obj;
        eval("obj=new " + className + "()");
        return obj;
    }
}
To be frank eval() is not a feature of TypeScript. Its there in JavaScript for long and TypeScript cannot take the credit for reflection. Since its demonstrated in TypeScript, the title of this post contains TypeScript.

Security warning

If the className is accepted from user, there are chances for attack. If they enter a string like below and we use that string as is to call this method, it will just execute malicious code.

String(); (function malicionsFunction(){//malicious code})();new String

Tuesday, May 3, 2016

TypeScripting AngularJS 1.x - Define module - improvements for big enterprise apps

Improvements for enterprise apps

We have see that there is a typed way to define modules and setup the Angular constructs such as services, controllers etc...This works great in small apps. But there is a problem, if we are developing an big enterprise app with many developers adding new controllers, directives frequently. In that situation, everybody will be competing for the one app / module file.

Below can be our aim when designing TypeScript Angular module class.
  • No need to repeat the ng-app name in every file.
  • There should be one central place for knowing what are the components registered.
  • Every angular component registered in the system should be testable using dependency injection.

How to fix it?

What if we expose a method in the Module to registerController, Directive etc...Those methods can be called by each file which contains different Angular components to register themselves? The object of Module can be exposed via singleton. Lets see the code below for the Angular module wrapper class.

CountryModule.ts

module CountryApplication {
    "use strict";
    export class CountryModule {
        //Do not expose the property as it is not expected to change from outside.
        private static currentCountryModule: CountryModule;
        public static getInstance(): CountryModule {
            return CountryModule.currentCountryModule;
        }
        private app: ng.IModule;
 
        constructor() {
            this.app = angular.module("CountryApp", []);
            CountryModule.currentCountryModule = this;
        }
        /** Acts as central place for registration. But somebody adds new controller they don't need to edit this file.
        */
        registerService(name: string, serviceConstructor: Function): void {
            this.app.service(name, serviceConstructor);
        }
        registerController(name: string, controllerConstructor: Function): void {
            this.app.controller(name, controllerConstructor);
        }
    }
    var hrApp: CountryModule = new CountryModule();
}

The code is self explanatory. We are just wrapping the actual Angular application inside CoutryModule class. Lets see how services can register to the ng application.

CountryMetadataService.ts

module CountryApplication {
    export class CountryMetaDataService {
        employees: Array<Country> = new Array<Country>(
            { id: 1, DisplayName: "India", Currency: "Indian Rupee", CurrencySymbol: "R" },
            { id: 2, DisplayName: "United States", Currency: "Dollar", CurrencySymbol: "$" }
        );
        GetAll(): Array<Country> {
            return this.employees;
        }
    }
    // Registering with angular app name in every file is difficult to maintain.
    // angular.module('CountryApp').service("CountryMetaDataService", CountryMetaDataService);
    CountryModule.getInstance().registerService("CountryMetaDataService", CountryMetaDataService);
}

An end to end template can be found in Github.com. This will get more scenarios on how to use TypeScript in AngularJS applications in TypeScript way.

Welcome to enterprise web app development.

Monday, March 28, 2016

TypeScripting AngularJS 1.x - Define module

As we know developing and maintaining a large application in pure JavaScript is really tough. One of the reason is its dynamic typing or its not TypeSafe. If we want to change a variable or function name that's it. There is no way to identify where all it used until we run. Of course we can do text search. But its difficult from the tooling perspective. So people going to TypeScript to develop JavaScript applications.

AngularJS is a JavaScript framework for developing enormous apps. If we use TypeScript there, we get more advantage. Since any valid JavaScript is valid TypeScript, people tend to write JavaScript inside TypeScript files without leveraging TypeScript features. But it works. It will definitely give difficulties in long term when maintaining the code.This series is aimed at how we can leverage TypeScript to code AngularJS application in the TypeSafe (compile time) way

Defining module 

It is easy.to define an Angular module via JavaScript.
var app = angular.module("<moduleName>", []);

But lets see how can we do it via TypeScript. Please note this require TypeDefinitions for AngularJS. If we are using Visual Studio, this can be installed via 'angularjs.TypeScript.DefinitelyTyped' package
var app: ng.IModule = angular.module("<moduleName>", []);

Then we can register controllers, services and directives to it. by calling app.controller(), service(), directive() respectively. But is that an object oriented way? Absolutely not. We need to wrap it inside a class. Lets see one sample below.
module CountryApplication {
    "use strict";
    export class CountryModule {
        private static _constructor = (() => {
            var countryApp: CountryModule = new CountryModule();
            countryApp.setup();
        })();
        app: ng.IModule;
        constructor() {
            this.app = angular.module("CountryApp", []);
        }
        setup() {
            var app1: ng.IModule = angular.module("<moduleName>", []);
            this.setupServices();
            this.setupControllers();
            this.setupDirectives();
            this.setupRoutes();
        }
        private setupServices(): void {
            this.app.service("CountryMetaDataService", ["$http",'$q',CountryMetaDataService]);
        }
        private setupControllers(): void {
            this.app.controller("CountryController",
                ['$scope', '$http','CountryMetaDataService', CountryController]);
        }
        private setupDirectives(): void {
            this.app.directive
        }
        private setupRoutes(): void {
        }
    }
}
We can see the things we were doing in Angular with JavaScript. But here we are just organizing, as a class. This gives us one view about our services, directives, controllers and how they are related each other.

The downside of this is every time a developer adds a new controller or service they need to modify this file.

Links