Click here to Skip to main content
12,450,347 members (51,031 online)
Click here to Skip to main content
Add your own
alternative version

Stats

31.1K views
1 download
29 bookmarked
Posted

TypeScript - 101 : The Basics

, 31 Jul 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
The article intends to provide a jump start for web developers on TypeScript

TypeScript -  101 : The Basics

Table of Contents

Introduction

     TypeScript

     Installing TypeScript

TypeScript Fundamentals

     TypeScript Types

     Type Inference

     Optional Type

Classes and Interface

     Classes

            Default and Optional Parameter

     Interfaces

     Inheritance

Modules

     Referencing Internal Modules

     Asynchronous Module Definition (AMD)

TypeScript with External Libraries

     Ambient Declarations

Summary

Appendix

Introduction

TypeScript

Today, JavaScript is a universal web language, one language which is supported by every browser, does not need any special installation. No web development today is possible without using JavaScript and JavaScript has moved its wings not only on client side development but as well as server side development like NodeJS. But, ask any developer who is learning JavaScript or coming from an Object Oriented background they would roll their eyes when asked about how easy it to do programming in JavaScript. One of the most powerful feature of JavaScript is it dynamic type wherein we can assign anything to any variable but this feature itself becomes a roadblock in large scale JavaScript application if we are not very careful. JavaScript also does not have a good IntelliSense and you will very rarely find errors at compile time, specially the type errors.

As stated on official TypeScript website “TypeScript is a typed superset of JavaScript that compiles to plain JavaScript”. TypeScript is not a replacement of JavaScript, it does not add any new features in JavaScript. TypeScript provides developers with features like type safety, compile time type checking, object oriented constructs on top of JavaScript, basically lets developers think in object oriented terms when writing JavaScript. The most amazing thing about TypeScript is, it compiles in JavaScript so we don’t have to support any new VM to run TypeScript which then can be referenced in a web page, used in server side like in NodeJS.

TypeScript is an open-source developed by Microsoft, but is in no way ties to Microsoft platform and can be used anywhere in any environment where there is a need to write JavaScript. Though Microsoft does provide a great support in Visual Studio for TypeScript and we will be using Visual Studio for our examples but we can use TypeScript compiler as well from command prompt to compile TypeScript in JavaScript (we will see a brief example of that as well).

Installing TypeScript

TypeScript is included in Visual Studio 2013 Update 2 by default and can be installed for Visual Studio 2012 from installer provided on TypeScript website. Current version at time of writing this paper is 1.0. TypeScript also provides support for other editors like sublime, Emacs and Vim. TypeScript also has a package which can be used in Node.js. All these installations can be found on TypeScript

Once the TypeScript is installed for Visual Studio, it will add a new Project and Item templates. This enables us to create new project for TypeScript as well as add TypeScript files to existing application.

TypeScript file template can be created in similar way as other files are, by selecting “Add New Item” and then selecting a TypeScript file.

All TypeScript files have *.ts extension. Visual Studio plugin for TypeScript automatically creates and updates a corresponding JavaScript file with same name whenever we modify the TypeScript file and save. This generated JavaScript file can then be used as a normal file and included in any web page.

When we create a TypeScript project a default “app.ts” file gets created within the project which has a default code implementation. Visual Studio also provides a side by side view of TypeScript file with corresponding JavaScript file and every time we save TypeScript file, we can see the change in JavaScript file as well. TypeScript file achieves this feature by creating a corresponding “*.js.map” file. Visual Studio uses this map file to map the TypeScript code with the generated JavaScript code. Also, browser like Chrome use these map files to help us debug TypeScript files directly instead of debugging JavaScript file.

In case you see that automatically compiling TypeScript does not create or update JavaScript check the options under Tool menu as shown below. This problem used to come normally in TypeScript versions before 1.0

<img src="TSOptions.png">

We can also generate JavaScript file from command line using “tsc.exe” command and passing <<filename>>.ts file, tsc.exe is available in “Microsoft SDK/TypeScript”.

TypeScript Fundamentals

TypeScript provides developers with object oriented concepts and compile time type checking on top of JavaScript which helps writing more structured, maintainable and robust code. TypeScript introduces few of the standard object oriented terms like Classes, Interfaces, Module and Variables which in end gets converted into various different forms of JavaScript. The code structure for a typical TypeScript file is shown below.

Module

Module is like a namespace in .Net world and can contain classes and interfaces. Modules do not have any feature of their own, they just provide a container which can be used to structure code in a logical form. Look at module just as a container of business/logical entity.

Interface

Interfaces are exactly like interfaces in .Net which provide a contract for the classes to implement. TypeScript helps in providing compile time error checking for the classes implementing these interfaces. If all the methods have not been implemented properly (including method signature), TypeScript flags those ate design time as well as compile time. Interesting thing about Interfaces is that they do not exist in JavaScript and hence when we compile a TypeScript file into JavaScript, Interfaces are omitted.

Classes

The concept of Classes is again very similar to .Net/Java world. Classes contains variables, properties and methods which form one logical entity. TypeScript also allows to set scope of the variable and functions with keyword like “private” and “public” though that scope does not have any effect on the JavaScript generated.

Functions

Functions are methods where the logic is implemented. TypeScript provides compile time support to make sure anyone calling the said function agrees to the input argument and return value type.

Variables

Variables are the fields defined inside a class or a function. TypeScript allows us to define a variable using keyword “var” and assign a data type to it. Once a data type is assigned any further usage of the variable has to be with same data type else TypeScript will generate error on design and compile time. TypeScript is also smart enough to infer the type of a variable and the treat it as that type when a variable is declared and initialized. In cases where TypeScript is not able to infer the type, it will assign that variable type of “any”.

TypeScript Types

TypeScript provides some primitive types (shown below) as well as a dynamic type “any”. “Any” is like “dynamic” keyword in C# wherein we can assign any type of value to the variable. TypeScript will not flag any type errors for variable of type “any”.

In TypeScript, we define a variable with a type by just appending the variable name with colon followed by the type name as shown in below example

var num: number = 30; //variable num is of type number

Below is the list of primitive types available in TypeScript

  • Number: the “number” is a primitive number type in TypeScript. There is no different type for float or double in TypeScript
  • Boolean: The “boolean” type represents true or false condition
  • String: The “string” represent sequence of characters similar to C#
  • Null: The “null” is a special type which assigns null value to a variable
  • Undefined: The “undefined” is also a special type and can be assigned to any variable

 

Array Type: TypeScript also allows developers to create array objects similar to that in .Net by just adding square brackets as shown in below example

TypeScript

JavaScript

var array: string[] = ['test', 'dummy'];
var first: string = array[0];
var array = ['test', 'dummy'];
var first = array[0];

Table 1

This allows us to create complex object in TypeScript with primitive types. In TypeScript array is accessed with zero based index.

TypeScript also allows us to create complex variables as shown in below example

 TypeScript

var name = { firstName: 'Homer', lastName: 'Simpson' };
name.firstName = 2; //This gives compile time error

 JavaScript

var name = { firstName: 'Homer', lastName: 'Simpson' };
name.firstName = 2; //No Error in JavaScript

Table 2

Also, in the above case notice that we had not defined the type of name variable, but TypeScript is smart enough to infer that name is a complex object with “firstName” and “lastName” string variables and if we try to assign anything other than string to either of these variables, TypeScript will show a design time error with a red line below name variable

Type Inference

As we saw above TypeScript provides type inference wherein even if we don’t define a variable with a type, TypeScript infers the type with the value with which we would have initialized the variable. If we don’t initialize the variable nor we define a type when declaring a variable, TypeScript assigns “any” type to the variable. But, as JavaScript does not distinguish between any of these types, all the variable will be same for JavaScript.

 TypeScript

var dummy; //any type
var num = 10; //number
var str = 'Hello TypeScript'; //string
var bln = true; //boolean
var stringArray = ['Homer', 'Simpson']; //string[]

 JavaScript

var dummy;
var num = 10;
var str = 'Hello TypeScript';
var bln = true;
var stringArray = ['Homer', 'Simpson'];

Table 3

Types are only valid for TypeScript and have no role in JavaScript generated. Types are just used by TypeScript for compile time checking and enable developers to make sure correct values are passed to variables.

Type checking is also available in functions. We can define types when defining the input parameters but, if type is not mentioned TypeScript takes it as “any”. In case of return type if we don’t define the type TypeScript will infer the type depending on the use of those variables.

 TypeScript

var addFunction = function (n1: number, n2: number, n3: number) {
var sum = n1 + n2 + n3;
return sum;
};
var str1: string = addFunction(10, 20, 30); //Gives compile time error as return type of a function is number and is being assigned to a string

var sum: number = addFunction(10, 20, 30); // This works
var result = addFunction(10, 20, 30); // This also works

 JavaScript

 var addFunction = function (n1, n2, n3) {
var sum = n1 + n2 + n3;
return sum;
};
var str1 = addFunction(10, 20, 30);
var sum = addFunction(10, 20, 30);
var result = addFunction(10, 20, 30);

Table 4

In above table we see that TypeScript uses type inference to determine that the “addFunction” has a “number” return type based on the input parameter types. When we try to assign the result of the function to a string variable TypeScript gives a design and compile error. This does not happen in JavaScript which will compile properly.  Also, if we would have not have defined type for variables “n1”, “n2”, “n3”, TypeScript would have assigned them “any” type and then it would have assigned return type as “any”. We can also explicitly define the return type by suffixing colon after the parameters and assigning the type for example

var addFunction = function (n1: number, n2: number, n3: number) : number {
var sum = n1 + n2 + n3;
return sum;
};

Optional Type

TypeScript also allows us to declare a variable in a function as optional so that anyone calling that function may or may not pass value for that variable. To make a parameter in a function as optional we need to add “?” to the variable name. Again, optional parameters don’t exist in JavaScript and hence those will not be handled there.

 TypeScript

var addFunction = function (n1: number, n2: number, n3?: number) : number {
var sum = n1 + n2 + n3;
return sum;
};
var sum: number = addFunction(10, 20);

 JavaScript

var addFunction = function (n1, n2, n3) {
var sum = n1 + n2 + n3;
return sum;
};
var sum = addFunction(10, 20);

Table 5

Optional parameter has to be the last parameter in the list and there cannot be a required parameter after the optional similar to C# convention. We can also use optional concept in variables/fields defined in classes, shown in next chapter.

Classes and Interface

Classes

TypeScript classes are basic unit of abstraction very similar to C#/Java classes. In TypeScript a class can be defined with keyword “class” followed by class name. TypeScript classes can contain constructor, fields, properties and functions. TypeScript allows developers to define the scope of variable inside classes as “public” or “private”.  It’s important to note that the “public/private” keyword are only available in TypeScript, once it’s converted to JavaScript there is no way to distinguish between the two and both can be called. TypeScript defines a constructor using keyword “constructor”.

 TypeScript

 class Student {
    private firstName: string;
    private lastName: string;
    yearOfBirth: number;    //Public scope by default
    schoolName: string;
    city: string;
    //Constructor            
    constructor(firstName: string, lastName: string, schoolName: string, city: string, yearOfBirth: number) {

        this.firstName = firstName;
        this.lastName = lastName;
        this.yearOfBirth = yearOfBirth;
        this.city = city;
        this.schoolName = schoolName;

    }
    //Function
    age() {
        return 2014 - this.yearOfBirth;
    }         
    //Function
    printStudentFullName(): void {
        alert(this.lastName + ',' + this.firstName);
    }
}

 JavaScript

 var Student = (function () {
    //Constructor
    function Student(firstName, lastName, schoolName, city, yearOfBirth) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.yearOfBirth = yearOfBirth;
        this.city = city;
        this.schoolName = schoolName;
    }
    //Function
    Student.prototype.age = function () {
        return 2014 - this.yearOfBirth;
    };

    //Function
    Student.prototype.printStudentFullName = function () {
        alert(this.lastName + ',' + this.firstName);
    };
    return Student;
})();

Table 6

In the above constructor defined in TypeScript we have few input variables which are then mapped to local variables inside a class, we can modify this constructor to implement implicit variable declaration and mapping by defining scope along with variable name in constructor definition as shown below.

constructor(private firstName: string, private lastName: string, public schoolName: string, public yearOfBirth: number) {}

In the above case, variables now are defined and declared inside the constructor argument only. The scope mentioned along with the argument becomes the scope of the variable for that class.

To consume the class the behavior is similar to C# where we use “new” keyword to initialize the class object, pass any parameters if the constructor requires and then call the functions or access public variables of the class.

var student = new Student('Tom', 'Hanks', 'World Acting School',1950);
 var age = student.age();
 var fullName = student.printStudentFullName();
 var schoolName = student.schoolName;

Default and Optional Parameter

In TypeScript we can also define any parameter with a default value, and then when calling that function we are not required to pass the value of those parameters. If we don’t pass the value then the function takes the default value assigned else the value passed in the function call is taken as shown in example below

constructor(private firstName: string, private lastName: string, public schoolName: string, public yearOfBirth: number = 1990){}

In the above example we have assigned an optional value to “yearOfBirth” field and if in case the calling function does not pass any value for this field, constructor will initialize this with 1990.

Similar is the case for Optional parameters we can define a parameter by adding a “?” after the parameter name. In this case when the function is called we don’t need to pass the value for that parameter.

Subject(subjectList?: string[]) {
   if (subjectList == null) {
      alert('Oh, You have not subscribed to any course');
    }
  }

Here, if we call subject method without passing any parameter value, TypeScript will not show any error.

Interfaces

TypeScript offers support for Interfaces to use them as a contract for classes similar to C#. To declare an interface, we use keyword “interface” followed by the interface name. Important thing to know about interfaces is that when compiled in JavaScript, interface code is ignored and there is no corresponding JavaScript generated.

interface IStudent {
     yearOfBirth: number;
     age : () => number;
   }

Classes implement interfaces using keyword “implement” followed by interface name. As in C#, classes can implement multiple interfaces and TypeScript does a design time check to make sure that the class is implementing all the methods of that interface.

class Student implements IStudent

Here Student class now will have to implement “age” method and define property “yearOfBirth” else TypeScript will show design time error with the error mentioning which property/method have not been implemented in the class.

Inheritance

Having classes and interface means TypeScript also support inheritance which is a very powerful feature and aligns writing client side code to the way we write C# code. Using inheritance we can extend classes, implement and extend interfaces and write code which very closes recognizes with OOPs. In TypeScript when we extend a base class in child class we use keyword “super” to call the constructor of base class or even the public methods of the base class.

To extend a class in TypeScript we use “extend” keyword after the class name and the followed by the class through which we need to extend. We can also inherit interfaces on other interfaces.

//Interface
interface IStudent {
    yearOfBirth: number;
    age : () => number;
}
//Base Class
class College {
    constructor(public name: string, public city: string) {
    }
    public Address(streetName: string) {             
        return ('College Name:' + this.name + ' City: ' + this.city + ' Street Name: ' + streetName);
    }
}
//Child Class implements IStudent and inherits from College
class Student extends College implements IStudent {
    firstName: string;
    lastName: string;
    yearOfBirth: number;
    //private _college: College;
    //Constructor            
    constructor(firstName: string, lastName: string, name: string, city: string, yearOfBirth: number) {
        super(name, city);
        this.firstName = firstName;
        this.lastName = lastName;
        this.yearOfBirth = yearOfBirth;
    }
    age () { 
        return 2014 - this.yearOfBirth;
    }
    CollegeDetails() {
        var y = super.Address('Maple Street');
        alert(y);
    }
    printDetails(): void {
        alert(this.firstName + ' ' + this.lastName + ' College is: ' + this.name);
    }
}

Modules

Modules in TypeScript have similar purpose as namespaces in C#, it allows us to group together logical code. Modules help us to follow “separation of concerns” concept in client side code wherein each module can have a specific role. Modules provide us with the flexibility by allowing us to import other modules, export features outside modules.

Everything inside of a module is scoped to that module hence, the classes and interfaces placed inside a module cannot be accessed outside until we explicitly provide scope for them with keyword “export”.

Modules are declared using “module” keyword. We can nest one module inside another module which can help us provide better code maintainability.

module Movie {
    class Comedy {
        constructor(public actorName: string) { }

        getAllMovies() {
            return (["Alien", "Paul Bart", "Home Alone"]);
        }

        getMoviesbyActor() {
            if (this.actorName === 'Seth Rogen') {
                return (["Observe and Report"]);
            }
            else {
                return (["Home Alone"]);
            }
        }
    }   
}

Here we have declared a module which has a class defined in it. Interesting thing to note is that the class “Comedy” is not visible outside the module “Movie” but can be accessed inside the “Movie” module as its in that scope. This helps in separation of code and provides relevant scope as per business needs.

To be able to access classes, interfaces or variables outside a module we need to mark those with keyword “export”. Once a class inside a module is marked with “export” keyword all the public variables, functions are also accessible outside the module.

Hence, modules helps us with minimizing the scope of classes and provides us with the more robust platform to manage client side code. In any application irrespective of the size of the application we would want to access modules inside other modules, get a reference, call the methods inside classes and so forth. To achieve this we would need to create dependencies between modules and make sure that the scripts are loaded on a page based on the dependencies, a module which is not dependent on any other module should be loaded first and so on.

In TypeScript we have two ways to add dependencies between modules as explained in following sections.

Referencing Internal Modules

TypeScript provides a system (this mechanism is also available in Visual Studio for JavaScript) by which we can make modules available inside other modules and even throughout the program. This can be achieved using reference comments on top of the module in which we want to reference other module. The dependencies for any module are defined on top of that module in form of comments.

/// <reference path="Sample.ts" />
  var college = new Sample.College('My College', 'My City');

Above we see that on adding a reference to Sample module (which is inside Sample.ts) we are able to access College class, provided College class is marked with “export” keyword. Reference comments can be added by just dragging and dropping a file, Visual Studio by default will add these comments on top of the file.

The reference comment informs compiler that the Sample module will be available before this module loads and hence compiler allows classes inside Sample module to be accessed here. By adding “reference” comment we also get auto-completion and design time compile checking for the classes. We can add as many “reference” comments as we need to add dependencies for a module.

With this approach we should be aware of the dependencies graph for each module and hence it is suitable for small or medium size applications. We have to make sure that all the dependencies are loaded before the specified module to make it work and this can cause major headache for large applications where there are numerous modules and their respective files.

Asynchronous Module Definition (AMD)

AMD allows modules to be loaded asynchronously on need basis. RequireJS is one such library which provides the mechanism to load modules on demand.  We just need to reference dependent modules using keyword “import” and RequireJS takes care of loading them at runtime. AMD manages the dependencies for each module and takes away the complexity of making sure all the dependent modules are loaded on the page before the specific module. RequireJS uses the concept of identifying who is dependent on whom and then loading them in that sequence.

This is a very useful technique for large scale web applications where we have lot of TypeScript/JavaScript files and it is a headache to maintain the dependency graph.

RequireJS handles module loading using configuration style programming. Rather than loading all the scripts in the specific order, using RequireJS we just define a startup/bootstarp file in our HTML page. RequireJS reads that and navigates to the startup file which would then as required call other modules and as an when we call other modules, RequireJS loads the dependencies on demand.

<!-- Below line initalizes requirejs and mentions the startup file. In this case main-->
   <script data-main="main" src="Scripts/require.js" type="text/javascript"></script>

Then in main.ts/main.js we define the start method in this case run() which would be responsible for loading start page, in this case a dataService.

main.ts

require.config({
    baseUrl : "."
}); 

require(["bootstrapper"], (bootstrap) => {
    bootstrap.run();
});

Bootstrapper.ts

import ds = require("DataService");

export function run() {
    var service = new ds.DataService();
}    alert(service.getMessage());

DataService.ts

export interface IDataService {
     msg: string;
     getMessage(): string;
    };

export class DataService implements IDataService {
     msg = 'Data from API Call';
     getMessage() { return this.msg; }
}

In summary, managing many TypeScript/JavaScript files is an important task which needs to be planned beforehand. For small scale applications managing dependencies is not a major concern as we can just “reference” style comments and make sure we load scripts in the defined order. But, if we know that the application is going to grow to large number of files then we should plan to have dependencies managed properly.

TypeScript with External Libraries

In the above chapters we have seen how TypeScript wraps the ugliness of the JavaScript in object oriented goodness, now it’s time to extend this goodness and add a little sweetener in it.

In today’s day and age it’s quite frequent to use external libraries for client side development, to name a few famous ones Jquery, Knockout, Toastr and most famous of them all Angular. TypeScript has a role to play with these libraries as well, it allows us to use these libraries as a reference in our TypeScript code using “Ambient Declarations”

Ambient Declarations

Ambient declaration is a way by which TypeScript provides all its features like autocompletion, type checking, design and compile time type safety for external libraries. TypeScript comes preloaded with definitions of DOM (document object model) and JavaScript API’s for example

window.onload = function () {
     var t: HTMLElement =    document.getElementById('id'); }

Here we see that in TypeScript if we type in “document” we get intellisense for all the methods available with “document”. This helps us writing native JavaScript in TypeScript and make sure that we are following correct structure for each method call.

TypeScript also has support for other popular libraries using their respective definition files. These files have an extension of “*.d.ts” and are used by TypeScript to add design time support and compile time checking. These files just contain the definition of all the functions supported by the library and does not have any implementation. All the libraries are available at TypeScript Definitions. To access these libraries we just need to include their corresponding “*.d.ts” using “reference comments”. Once we have included this file we will have access to the libraries classes and function for example if we include Jquery.d.ts file, we will have access to “$” function and TypeScript will also provide intellisense for all the Jquery functions.

/// <reference path="typings/jquery.d.ts" />
    document.title = 'Hello TypeScript';
    $(document).ready(function() {
    var v;
    });

Similarly, we can use definition files of angular to write client code in TypeScript, sample shown below.

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

export class DataService {
        private videos: string[]
        private moviesApiPath: string;
        private categoriesApiPath: string;
        private httpService: ng.IHttpService;  //Note the type ng.IHttpService
        private qService: ng.IQService;        //Note the angular promises

        getAllMovies(fetchFromService?: boolean): ng.IPromise<any> {
            var self = this;

            if (fetchFromService) {
                return getMoviesFromService();
            } else {
                if (self.movies !== undefined) {
                    return self.qService.when(self.videos);
                } else {
                    return getVideosFromService();
                }
            }

Summary

For each of the features in TypeScript we have been relating to corresponding features in OOPs language such as C# and Java but, we need to keep in mind that TypeScript is not a OOPs language. In fact, TypeScript is just a tool on top of JavaScript which provides us with more robust code structure, type safety. TypeScript enhances the productivity of developers writing JavaScript code and it in itself does not provide any specific functionalities or features like libraries such as Jquery.

Most of the features which we use in TypeScript gets removed from the compiled JavaScript file and we are left with nothing more than a pure JavaScript code. TypeScript is open source and is no way tied to Microsoft or .Net technologies. Developers writing code in JavaScript can use TypeScript with various different IDE’s apart from Visual Studio like Sublime Text, VIM. There are various forums/blogs available on TypeScript and the development community has started to use TypeScript with their respective libraries. Resharper is also providing support for TypeScript in its Version 8 release which allows developers easier path to refactor, create functions and other features which Visual Studio users are so accustomed to use.

Appendix

Reference websites for TypeScript

http://www.typescriptlang.org/

http://typescript.codeplex.com/

http://blogs.msdn.com/b/typescript/archive/2014/04/02/announcing-typescript-1-0.aspx

http://www.barbarianmeetscoding.com/blog/2013/08/20/learn-typescript-to-improve-your-javascript/

http://gilamran.blogspot.in/2014/04/typescript-for-javascripters.html

Reference websites for RequireJS

http://requirejs.org/

Reference website for TypeScript with Angular

http://www.dotnetcurry.com/showarticle.aspx?ID=1016

Reference website for Resharper

http://blog.jetbrains.com/dotnet/2014/03/17/more-typescript-support-in-resharper-8-2/

 

Contact Me: You can contact on twitter @ohri_sachin

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

sachinohri
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

 
QuestionVery well written and good to begin with Pin
Talking Dotnet7-Jan-16 1:21
memberTalking Dotnet7-Jan-16 1:21 
GeneralMy vote of 5 Pin
Anurag Gandhi10-Dec-15 18:13
professionalAnurag Gandhi10-Dec-15 18:13 
QuestionThankyou Pin
al13n11-Sep-15 1:04
memberal13n11-Sep-15 1:04 
GeneralLike Pin
Brian_Lowe6-Aug-14 12:30
memberBrian_Lowe6-Aug-14 12:30 
GeneralGood article but images are missing Pin
Member 109867191-Aug-14 18:22
memberMember 109867191-Aug-14 18:22 
QuestionNice article Pin
Member 1039592431-Jul-14 22:32
memberMember 1039592431-Jul-14 22:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160826.1 | Last Updated 31 Jul 2014
Article Copyright 2014 by sachinohri
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid