Introduction
AngularJS is a JavaScript framework to create web applications with MVC on client side. Using AngularJS, you can create robust web applications having features such as two-way data binding, HTML templates, client side MVC framework, dependency injection and directives. Apart from this, each piece of code you write is testable.
Typescript is known to be a superset of JavaScript. Developed by Microsoft, its aim is to provide type safety and principles of OOP to existing JavaScript. As such, each piece of JavaScript code is always backward compatible to typescript counterpart.
In this tutorial, we will create a sample web application using AngularJS 1.x and Typescript.
We will be creating a web application where user can check whether his email or username has been compromised, using API provided by haveibeenpwned.com.
Background
This tutorial assumes you are a .NET developer and using Visual Studio 2013 as primary code editor. It is also assumed you have working knowledge of AngularJS with JavaScript as well as know how to use npm and bower.
Using the Code
We will be using the following project structure:
/scripts
/modules
/HaveIBeenPwned
/content
/css
/typings
/angularjs
/jquery
index.html
So let's get started.
Using Visual Studio 2013, create an empty ASP.NET Web Application named “HaveIBeenPwned
”.
Now, we need to add JavaScript files related to angular-core
and angular-route
. For that, we will use Bower. Execute the following commands in git window to download the dependencies.
bower install angular
bower install angular-route
Next step is to download type declaration files of angular. These would help in intellisense feature of Visual Studio. To do that, we need to install a node module “tsd
” : Typescript Definition Manager.
npm install -g tsd
Once the module is installed, we will use it to download declaration files.
tsd install angular
tsd install angular-route
This will create a new directory called typings with a sub directory called angularjs. Within will be the two Angular declaration files you just installed. As AngularJS has a dependency on jqLite, the declaration files for jQuery will also be downloaded. Once everything is downloaded, include all dependencies in Visual Studio. The solution explorer should look like this:
Next, we are going to create AngularJS related files. Create app.ts in scripts folder. This will be app.js file for web application and will be different from module specific app.js. Create a new app.module.ts in scripts/modules/HaveIBeenPwned folder. This will module specific app.js. Add the following code to app.module.ts.
module HaveIBeenPwned {
'use strict';
angular.module('HaveIBeenPwned', ['ngRoute']);
}
The above code will create a new module named HaveIBeenPwned
. Inside that, it will create a new angular module with the same name and it will use dependency injection to inject module ngRoute
. Typescript modules ensures separation of concern. Next, we need to configure angular routes. Instead of using traditional code to inject dependencies on config function, we will use different code to leverage Typescript. Consider the following piece of code.
module HaveIBeenPwned {
'use strict';
function routes($routeProvider: ng.route.IRouteProvider) {
}
routes.$inject = ['$routeProvider'];
angular.module('HaveIBeenPwned')
.config(routes);
}
We used Typescript type declaration on function parameters. Next step will be to configure routes for our module. Add the following code inside newly created routes function
.
function routes($routeProvider: ng.route.IRouteProvider) {
$routeProvider
.when("/searchMyHandle", {
templateUrl: '/scripts/modules/HaveIBeenPwned/_searchView.html',
controller: 'SearchHandleController'
});
}
You will also start seeing the benefit of using Typescript in Visual Studio. As a seasoned C# developer, I find myself using the same experience to write Typescript code.
Next, we will create SearchHandleController
in Typescript using classes. In order to inject the dependencies in Typescript
class, you need to use static $inject
. Add a new Typescript file named SearchHandleController.ts and add the following code to it.
module HaveIBeenPwned {
class SearchHandleController {
static $inject = ['HaveIBeenPwnedService'];
constructor(private haveIBeenPwnedService: IHaveIBeenPwnedService) {
}
}
angular.module('HaveIBeenPwned')
.controller('SearchHandleController', SearchHandleController);
}
In the above class, we are trying to inject dependency HaveIBeenPwnedService
, which we are yet to create. You don’t need to create separate variables in Typescript just to make them public
or private
. You can use constructor to do that. Whatever access modifier you assign to variable, it will be added to properties of that class. The class which we have created is present under module HaveIBeenPwned
but is not accessible outside its module. To do that, we need to mark it with keyword Export
. So, the above code will be changed to:
export module HaveIBeenPwned {
Next step is creation of HaveIBeenPwnedService
. Add a new Typescript file named HaveIBeenPwnedService.ts to modules folder and add the following code:
module HaveIBeenPwned {
export interface IHaveIBeenPwnedService {
check(handle: string): ng.IPromise<{}>;
}
class HaveIBeenPwnedService implements IHaveIBeenPwnedService {
static $inject = ['$http'];
constructor(private $http: ng.IHttpService) {
}
check(handle: string): ng.IPromise<{}> {
return this.$http.get("https://haveibeenpwned.com/api/v2/breachedaccount/" + handle);
}
}
angular
.module('HaveIBeenPwned')
.service('HaveIBeenPwnedService', HaveIBeenPwnedService);
}
Now, we will go back to our controller class and use the service to call the API.
private hackedAccount: HackedAccount[];
submit(handle: string) {
this.haveIBeenPwnedService.check(handle).then
((result: ng.IHttpPromiseCallbackArg<HackedAccount[]>) => {
this.hackedAccount = result.data;
})
.catch((reason) => {
console.log(reason);
});
}
Since HackedAccount
model is not available, add a new Typescript file named HackedAccount.ts and add the following code to it.
module HaveIBeenPwned {
export class HackedAccount {
Title: string;
Name: string;
Domain: string;
BreachDate: string;
AddedDate: string;
PwnCount: number;
Description: string;
DataClasses: string[];
IsVerified: boolean;
LogoType: string;
}
}
Next, we need to create _searchView.html. Add a new html page to the module folder and insert the following code to it.
<div>
<label>
Enter your email address:
<input type="email" id="emailAddress"
name="emailAddress" ng-model="shc.emailAddress"
ng-enter="shc.submit(shc.emailAddress)">
</label>
</div>
<button ng-click="shc.submit(shc.emailAddress)">Check</button>
<table>
<tbody>
<tr ng-repeat="hackedAccount in shc.hackedAccounts">
<td>{{hackedAccount.Title}}</td>
</tr>
</tbody>
</table>
Once everything is done, build the solution and run it.
Points of Interest
The above tutorial teaches us how we can create AngularJS 1.x web applications using Typescript.
History
- 28/11/2015 - Initial version