TypeScript Generics

TypeScript supports parameterized types, also known as generics, which can be used in a variety of scenarios. For example, you can create a function that can take values of any type, but during its invocation, in a particular context, you can explicitly specify a concrete type.

Take another example: an array can hold objects of any type, but you can specify which particular object types (for example, instances of Person) are allowed in an array. If you were to try to add an object of a different type, the TypeScript compiler would generate an error.

Generics syntax

The following code snippet declares a Person class, creates two instances of it, and stores them in the workers array declared with the generic type. Generic types are denoted by placing them in the angle brackets (for example, ).

class Person {
    name: string;
}

class Employee extends Person{
    department: number;
}

class Animal {
    breed: string;
}

let workers: Array<Person> = [];

workers[0] = new Person();
workers[1] = new Employee();
workers[2] = new Animal();  // compile-time error

Here we declare the Person, Employee, and Animal classes and a workers array with the generic type. By doing this, we announce our plans to store only instances of the class Person or its descendants. An attempt to store an instance of an Animal in the same array will result in a compile-time error.

Nominal and Structural type systems

After using generics in Java for 10 years, I quickly noticed that the syntax is the same and was about to check off this syntax element as “got it”. But it was a little too soon. While Java, C++, or C# use nomimal type system, TypeScript uses the structural one. In the nominal system, types are checked against their names, but in a structural system by their structure.

With the nominal type system the following line would result in an error:

let person: Person = new Animal();

With a structural type system, as long as the structures of the type are similar, you may get away with assigning an object of one type to a variable of another. Let’s illustrate it by adding the property name to the class Animal as seen on the screenshot below.

Now the TypeScript compiler doesn’t complain about assigning an Animal object to the variable of type Person. The variable of type Person expects an object that has a property name, and the Animal object has it. This is not to say that Person and Animal represent the same types, but these types a compatible. Trying to assign the Person object to a variable of type Animal will result in the compilation error “Property breed is missing in type Person”:

let worker: Animal = new Person(); // compilation error

Can you use generic types with any object or a function? No. The creator of the object or function has to allow this feature. If you open TypeScript’s type definition file (lib.d.ts) on GitHub and search for “interface Array,” you’ll see the declaration of the Array, as shown below.

The <T> in line 1008 means TypeScript allows you to declare a type parameter with Array and the compiler will check for the specific type provided in your program. The next code listing specifies this generic <T> parameter as <Person>. But because generics aren’t supported in JavaScript, you won’t see them in the code generated by the transpiler. It’s just an additional safety net for developers at compile time.

You can see another T in line 1022 in figure B.7. When generic types are specified with function arguments, no angle brackets are needed. But there’s no actual T type in TypeScript. The T here means the push method lets you push objects of a specific type into an array, as in the following example:

workers.push(new Person());

Creating your own parameterized types

You can create your own classes or functions that support generics as well. In the next listing, we defined an interface Comparator that declares a method compareTo() expecting the concrete type to be provided during this method invocation.

interface Comparator {                   // 1
    compareTo(value: T): number;
}

class Rectangle implements Comparator {    // 2

    constructor(private width: number, private height: number){};

    compareTo(value: Rectangle): number{   // 3
        if (this.width*this.height &gt;= value.width*value.height){
            return 1;}
        else  {
            return -1;
        }
    }
}

let rect1:Rectangle = new Rectangle(2,5);  
let rect2: Rectangle = new Rectangle(2,3);

rect1.compareTo(rect2)===1? console.log("rect1 is bigger"): 
                            console.log("rect1 is smaller") ;   // 4


class Programmer implements Comparator {    // 5

    constructor(public name: string, private salary: number){};

    compareTo(value: Programmer): number{  // 6
        if (this.salary &gt;= value.salary){
            return 1;}
        else  {
            return -1;
        }
    }
}

let prog1:Programmer = new Programmer("John",20000);
let prog2: Programmer = new Programmer("Alex",30000);

prog1.compareTo(prog2)===1? console.log(${prog1.name} is richer):
                           console.log(${prog1.name} is poorer) ;  // 7

1. Declare an interface Comparator with a generic type

2. Create a class that implements Comparator specifying the concrete type Rectangle

3. Implement the method for comparing rectangles

4.Compare rectangles (the type T is erased and replaced with Rectangle)

5. Create a class that implement Comparator specifying the concrete type Programmer

6.Implement the method for comparing programmers

7. Compare programmers (the type T is erased and replaced with Programmer)

Even though generics are erased during the JavaScript code generation, use them to minimize the number of runtime errors. When you use libraries or frameworks written in TypeScript, you have no choice but use generics to use the API provided by these libraries.

If you live in New York, stop by at the Java SIG meetup on August 23, 2017 where I’ll be delivering a presentation “TypeScript for Java Developers”.

Advertisements

JavaScript rest and spread operators

Back in 2015, the ECMAScript 6 spec was released and at the time of this writing, all major browsers (except the stubborn IE11) support its syntax. In this article, I’ll show you a couple of useful operators: rest and spread.

Due to lack of imagination, the creators of ES6 spec decided to use the same notation (…) for both rest and spread operators, but let’s not whine. If everything would be simple, our salaries would be lower. So let’s start with getting familiar with the rest operator.

Rest parameters

In ES5, writing a function with a variable number of parameters required using a special object called arguments. This object is similar to an array, and it contains values corresponding to the arguments passed to a function. The implicit arguments variable could be treated as a local variable in any function.

The rest operator is used to pass a variable number of arguments to a function, and it has to be the last one in the arguments list. If the name of the function argument starts with the three dots, the function will get the rest of the arguments in an array. The ES6 rest operator is represented by three dots (…).

For example, you can pass multiple customers to a function using a single variable name with a rest operator:

function processCustomers(...customers){
  // implementation of the function goes here
}

Inside this function, you can handle the argument customers the same way you’d handle any array. Imagine that you need to write a function to calculate taxes that must be invoked with the first argument income, followed by any number of arguments representing the names of the customers. The following code shows how you could process a variable number of arguments using first the ES5 and then the ES6 syntax. The calcTaxES5() function uses the object named arguments, and the function calcTaxES6() uses the ES6 rest operator:

// ES5 and arguments object
  function calcTaxES5(){

      console.log("ES5. Calculating tax for customers with the income ",
                             arguments[0]);   // income is the first element

      // extract an array starting from 2nd element
      var customers = [].slice.call(arguments, 1);

      customers.forEach(function (customer) {
          console.log("Processing ", customer);
      });
  }

  calcTaxES5(50000, "Smith", "Johnson", "McDonald");
  calcTaxES5(750000, "Olson", "Clinton");

// ES6 and rest operator
  function calcTaxES6(income, ...customers) {
      console.log("ES6. Calculating tax for customers with the income ", income);

      customers.forEach(function (customer) {
          console.log("Processing ", customer);
      });
  }

  calcTaxES6(50000, "Smith", "Johnson", "McDonald");
  calcTaxES6(750000, "Olson", "Clinton");

Both functions, calcTaxES5() and calcTaxES6() produce the same results:

ES5. Calculating tax for customers with the income 50000
Processing Smith
Processing Johnson
Processing McDonald
ES5. Calculating tax for customers with the income 750000
Processing Olson
Processing Clinton
ES6. Calculating tax for customers with the income 50000
Processing Smith
Processing Johnson
Processing McDonald
ES6. Calculating tax for customers with the income 750000
Processing Olson
Processing Clinton

See it in action on CodePen (click on the Console at the bottom to see the output): https://codepen.io/yfain/pen/WEjLwR?editors=0011

There’s a difference in handling customers though. Because the arguments object isn’t a real array, we had to create an array in the ES5 version by using the slice() and call() methods to extract the names of the customers starting from the second element in arguments. The ES6 version doesn’t require us to use these tricks because the rest operator gives you a regular array of customers. Using the rest arguments made the code simpler and more readable.

The spread operator

The ES6 spread operator is also represented by three dots (…) like the rest parameters, but if the rest operator can turn a variable number of parameters into an array, the spread operator can do the opposite: turn an array into a list of values or function parameters.

Say you have two arrays and you need to add the elements of the second array to the end of the first one. With the spread operator it’s one line of code:

array1.push(...array2);

You can also create a copy of an array as follows

let arrayCopy = [...myArray];

Finding a maximum value in the array is also easy with the spread operator:

const maxValue = Math.max(...myArray);

In some cases, you want to clone an object. In cases when you have an object that stores the state of your app, you may want to create a new object when one of the state properties changes. In other words, you don’t want to mutate the object but want to clone it with modification of one or more properties. One way to implement immutable objects is by using the Object.assign() function. The following code snippet will create a clone of the object first, and then will do another clone with changing the lastName at the same time:

// Clone with Object.assign()
const myObject = { name: "Mary" , lastName: "Smith"};
const clone = Object.assign({}, myObject);
console.log(clone); 

// Clone with modifying the `lastName`
const cloneModified = Object.assign({}, myObject, {lastName: "Lee"});
console.log( cloneModified); 

The spread operator offers a more concise syntax for achieving the same goals:

// Clone with spread
const cloneSpread = {...myObject};
console.log(cloneSpread);

// Clone with modifying the `lastName`
const cloneSpreadModified = {...myObject, lastName: "Lee"};
console.log(cloneSpreadModified);

See it in CodePen: https://codepen.io/yfain/pen/XaRGYa?editors=0011

If you haven’t been using spread and rest operators yet, it’s a big mistake. Huge.

This article is just an intro to using the rest and spread operators. For more info, read the docs here and here.

TypeScript: callable interfaces

TypeScript is a superset of JavaScript and over the last year it’s gaining popularity by leaps and bounds. Angular 2 and RxJS 5 are written in Typescript. I believe about a million of developers are using TypeScript today for app development (this is not official stats). I’m using TypeScript for more than a year and it’s so much more productive than JavaScript! For me (a Java developer), TypeScript makes a lot more sense than JavaScript. But if your main language was JavaScript, some of the TypeScript’s concepts might look foreign for you. I’m planning to write a couple of blogs illustrating TypeScript syntax.

Web browsers don’t understand TypeScript and there’re no plans to change this any time soon. So if you’ll write a program in TypeScript, it has to by transpiled (think compiled) into JavaScript first. I’m not going to discuss the TypeScript compiler here, but will be using the Playground, where you can write code fragments in TypeScript, and they’ll be immediately transpiled into JavaScript (it’s going to be the ECMAScript 5 version).

TypeScript supports different flavors of interfaces. Today we’ll get familiar with a callable interface that contains a bare function signature (a signature without a function name). I’ll show you the syntax first and then will explain how a callable interfaces are useful. The following example shows a bare function signature that takes one parameter of type number and returns a boolean.

(percent: number): boolean;

The bare function signature indicates that when this function will be implemented it’s going to be callable. So what’s the big deal? Let’s consider an example that declares IPayable interface, which will contain a bare function signature. In our company work employees and contractors that will be represented by a class Person. The rules for increasing pay of employees and contractors are different, and I’ll create separate functions that implement these rules. These functions will be passed as arguments to the constructor of the class Person and will be invoked inside the constructor of the Person instances.

interface IPayable { // <1>
    (percent: number): boolean;
}

class Person  {
    constructor(private validator: IPayable) { // <2>
    }

    increasePay(percent: number): boolean { // <3>
        return this.validator(percent);
    }
}

let forEmployees: IPayable = (percent) => { // <4>
        console.log("Increasing salary by ", percent);
        return true;
    };

let forContractors: IPayable = (percent) => { // <5>
    var increaseCap: number = 20;

    if (percent < increaseCap) {
      console.log("Increasing hourly rate by", percent);
      return true;
    } else {
      console.log("Sorry, the increase cap for contractors is ",
                                         increaseCap);
      return false;
    }
}

let workers: Array<Person> = [];

workers[0] = new Person(forEmployees); // <6>
workers[1] = new Person(forContractors);

workers.forEach(worker =>worker.increasePay(30)); // <7>

1. A callable interface that include a bare function signature.

2. We declare that the constructor of the Person class takes an implementation of the callable interface IPayable as an argument.

3. The increasePay() method invokes the bare function on the passed implementation of IPayable, supplying the pay increase value for validation.

4. The rules for salary increases for employees are implemented using the arrow function expression.

5. The rules for pay increases for contractors are implemented using the arrow function expression.

6. Instantiates two Person objects, passing different rules for pay increases.

7. Invokes increasePay() on each instance, validating the 30% pay increase.

First I’ll enter the above code in the TypeScript playground on the left, and the generated JavaScript code will be shown on the right (see http://bit.ly/2hUdsGn). Read the JavaScript code – it should help you understanding what’s going on. Note, that there are no traces of our IPayable interface on the right since JavaScript doesn’t support interfaces.

play

If you click on the button Run and open the browser’s console you’ll see the following output:

Increasing salary by 30
Sorry, the increase cap for contractors is 20

Cool. But in JavaScript you can also pass a function as an argument to a higher order function (constructor in our case), right?

Now imagine that you’re supposed to pass a function with a certain signature to a higher order function, but made a mistake and passed a wrong function. This will result in a runtime error.

Callable interfaces allow you to to catch this mistake during the development stage. For that we declare the signature of a function that has to be passed to the constructor of the instance of the Person object.

Now purposely introduce an error – declare a function with the wrong signature (do it on the left side at the playground):

let forTempWorkers = () => 
      console.log("Can't increase salary for temps"); 

Try to pass it to the constructor to a Person:

workers[0] = new Person(forTempWorkers); 

TypeScript will immediately highlight the above line as erroneous, and you’ll catch this error during dev time whereas in JavaScript this error would silently sneak into your code causing the app to blow up during the runtime.

play2

So callable interfaces are your friends, aren’t they?

My Angular 2 presentations for 2017

In 2017 I’m planning to speak at several conferences related to development of Web applications with the new Angular 2 framework. Below is the list of my presentations (each one is 90-min long). All of them can be delivered as a 2-day workshop in your organization.

Mastering TypeScript

TypeScript is a superset of JavaScript, which allows you to be more productive in writing JavaScript applications. The syntax of this language is pretty easy to pick up for anyone who’s familiar with such object-oriented languages as Java or C#. During this presentation you’ll learn the syntax of this language and will understand the benefits it brings to the table.

Make a facelift to your Angular 2 app with UI libraries

Commercial applications need to be good looking, which means that you should pick up a rich library of UI components for your app. While Angular Material library offers two dozen of great looking components, this may not be enough for your application needs. The good news is that there are other libraries that you can use. In this presentation we’ll start with an overview of Angular Material components. Then we’ll proceed with another open-source library called PrimeNG, which offers more than 70 UI components. Finally, we’ll review the code of an Angular 2 app that uses both Angular Material and PrimeNG components.

Angular 2 for Java developers

Angular 2 is a complete re-write of the super popular Web framework AngularJS. According to Pluralsight survey, Angular leads the list of what developers want to learn in 2016. Angular 2 is a component-based framework that will have an effect in JavaScript community similar to what Spring framework did for Java. This presentation is an overview of this hot framework, which in combination with TypeScript, finally made Web development understandable for Java developers. At the end of the presentation you’ll see a sample Web application written in Angular 2 on the front and Java on the server.

Angular 2: Working with the component router

In this session you’ll see how to use the router that comes with Angular 2 Final. We’ll start with configuring the navigation in a simple app. Then you’ll see how to pass data to routes, work child routes, and create apps with multiple router outlets (auxiliary routes). We’ll also review a unit-test configuration for testing router. Finally, you’ll see how how to lazy load modules using the router.

Angular 2: Communication with the server via HTTP and WebSocket protocols

In this session you’ll see how create an Angular 2 app that can communicate with the servers via a pull (HTTP) and push (WebSocket) modes. We’ll program a simple Node server and then will go through a number of code samples that communicate with it using HTTP and WebSocket protocols. We’ll start with creating a simple NodeJS server, and then will enable it to handle HTTP requests from an Angular 2 app. Then you’ll see how to wrap a service into an observable stream. Finally, we’ll teach our server to perform a data push to an Angular 2 client using the WebSocket protocol.

Implementing inter-component communication in Angular 2

Angular 2 is a component-based framework with a well-defined API for passing data to and getting data from a component. Any application is a tree of components that often need to communicate with each other.
In this presentation you’ll see how to create reusable application components that can exchange data with each other in a loosely-coupled manner. You’ll see how components can communicate via a common parent or via an injectable service. You’ll see how to pass data using component router, input and output parameters, events and callbacks. You’ll also learn how to use projection (formerly known as transclusion) to pass HTML fragments to a component’s template. We’ll also touch upon the incorporation of the third-party JavaScript libraries into an Angular 2 app.

Using Observable Streams in Angular 2

Angular 2 includes RxJS, which is a library of reactive extensions built on the premise that everything is an observable stream.

Observables allow to introduce the push model to your application. First we’ll get familiar with the RxJS library, and then will continue reviewing observables in Angular 2. In this presentation you’ll see how to treat UI events, HTTP, and WebSocket connections as observable streams that push data. You’ll see how to wrap up any service into an observable stream so your application components can subscribe to it.

Angular 2 Tooling

Learning Angular 2 is easier than AngularJS, and developing in TypeScript is more productive than in JavaScript. But setting up the project and deploying the application is not straightforward. This presentation is not about the Angular 2 syntax. We’ll discuss the development process with Angular 2 starting from setting up the project to deploying an optimized application. We’ll start with discussing the Angular/TypeScript project structure and the proceed with such topics as using the module loader SystemJS, installing type definition files, bundling the app with Webpack and deployment in dev and prod. Finally, we’ll go through the process of scaffolding and bundling projects using the Angular CLI tool.

Adding PrimeNG UI components to Angular CLI projects

Angular 2 CLI is a scaffolding tool and code generator that can be used for the real world projects. It saves you a lot of typing and spares you from worrying about config files for TypeScript compiler, testing frameworks, project bundler (it uses Webpack), and deployment.

PrimeNG is an excellent library of 70+ Angular 2 UI components. In this blog I’ll list the steps you need to perform to generate new project with Angular CLI and add PrimeNG library to this project.

If you don’t have Angular CLI installed yet, install it globally:

npm install @angular/cli -g

In the terminal window generate a new project, e.g. primeng_with_cli. Since I just want Angular CLI to generate only app compnent and module files, I’ll specify the option to generate inline template and styles and don’t bother with the test spec:


ng new primeng_with_cli --it --is --spec=false

Change to the newly created directory

 
cd primeng_with_cli

Add font awesome and PrimeNG as dependencies in package.json, e.g.


"font-awesome": "^4.6.3",

"primeng": "^1.0.0-beta.20",

Since the package.json was modified, install the above dependencies:

npm install

PrimeNG requires certain global styles so its components look pretty. Angular CLI projects have a config file angular-cli.json, where you can configure project settings, and in particular it has the property styles, which is the right place to add global style. Yes, I’m talking about the style tages that you’d add in the index.html in a regular Web app.

Angular CLI generate an empty file style.css and you need to add three more CSS file that are needed for PrimeNG:


"styles": [
    
  "styles.css",

  "../node_modules/primeng/resources/themes/omega/theme.css",

  "../node_modules/font-awesome/css/font-awesome.min.css",

  "../node_modules/primeng/resources/primeng.min.css"

] 

For sanity check run your new app by entering the following command in the terminal window:

ng serve

Open the app in the browser at 
http://localhost:4200, and Webpack dev server will happily render the single-page app with the text app works! This is a basic app that Angular CLI generated for you.

Now you need to modify the code in the generated dir app.component with the code that uses PrimeNG components. You can take the sample code from this blog. You’ll need to add required PrimeNG components to imports and declarations in the application module file app.module.ts.

The dev version of the app works, and now let’s see the prod version of this cool app. To prepare a production build run this command:

ng build --prod

Angular CLI will create bundles and will deploy all the files in the dist directory of your project. Take a peek into this directory and you’ll see the bundles that are available as .js files as well as their gzipped versions. The question is, how can we serve the existing gzipped files without having the web server do it for us? A simple solution is to install a static Node server that knows how to do it. Just add node-static package as dev dependency in package.json and install it:


"node-static": "^0.7.9" 
npm install

Finally, add the following npm script command in scripts section in package.json:



"serve:dist": "static dist -H '{\"Cache-Control\": \"no-cache, must-revalidate\"}' -z"

Start the static server and it’ll serve the optimized app on port 8080:



npm run serve:dist

NOTE: Creators of PrimeNG promised to add AoT support in the release candidate that will be available within a couple of weeks. When it’s done, you’ll be able to create smaller bundles by running this command:

ng build --prod --aot

That’s all folks!

My two cents on the npm scandal

If you haven’t heard the story, here’s the gist of it. A guy named Azer Koçulu published 250(!) open source packages in the popular repository npmjs.org, which is a central repo for all JavaScript developers (it’s like Maven Central for Java developers).  One of the packages was named kik. Unfortunately for Azer (and all of us), there is a company with the same name, and they decided to publish the package with the same name on NPM. Due to the name conflicts, they contacted Azer asking him to rename his package that was already used by many users. Here’s the Kik corporation’s  version of the story. And this is what Azer wrote.

This is really sad. I’m with Azer 100%. There is a corporate world and there is an open source world. The corporate world loves using free and open source libraries and frameworks that help them making money. But they won’t think twice and will invest hundreds of thousands of dollars to win the case against Azer if need be.

Why a company with 270 million users rejected Azer’s offer to buy the name from him for mere $30K? Because they are a bunch of dicks as Azer correctly put it. They want free stuff.

There should be some international law that will make the commercial and the open source worlds live in parallel dimensions. If one corp uses a trademarked term from another corp, it can be sued. But they should not reach out to the open source world imposing their rules there.

We are using the JavaScript framework Jasmine for unit testing. I have a suspicion that there are some other uses of the word Jasmine.  Beside being a plant, a trading companya nail salon in Brooklyn,NY, a Thailand telecom company there are thousands establishments that use this word in their names. Now any of them can write a package that prints Hello World (even a plant can do it), and write a letter to NPM to remove the jasmine package from there.

Guys, this may open a can of worms. kik.com should back off!

Part 2 or is my application at risk

You might by thinking, “I don’t really care cause I’m not using any of Azer’s packages. I’m using Angular developed by a large company that employs hundreds of lawyers”. Wrong. In modern JavaScript ecosystem it’s very difficult to use just one thing. I’ll give you an example using one our simple projects that uses five npm packages: Angular 2, TypeScript, Jasmine, Karma, and live-server. I’ll give you a little quiz. How many packages will be installed on your computer to get these five things? Just take a look at the end of log file of the “npm install” command that I ran on my computer to install these five things.

log

That’s right. Those five packages had dependencies and 263 npm packages where installed on my computer in less than a minute. Some of them were developed by big companies, but most of them were developed by one person like Azer.

To be more specific, my application heavily depends on module loader called SystemJS (see the package #259), which was developed by the guy named Guy Bedford, a respected developer who contributed tons of code to the open source community (btw, Guy is also the author of JSPM package manager). What if for whatever reason Guy will become as angry as Azer and will remove SystemJS from npm? This will affect thousands of projects. These projects won’t stop working, because SystemJS is already installed locally, but lots and lots of people will need to spend time and find a replacement or start fixing builds, bugs and adding features to the local version of SystemJS instead of working on their applications.

Some open source developer nicely illustrated a scenario when an 11-line library responsible for left-padding strings was removed from npmjs.org. Check this out 🙂 David Haney raises the right question, “Have we forgotten how to program?

Part 3 OMG, what do I do?

Nothing. Just accept the reality of today’s open source world. At least I live with an assumption that any of the above 263 packages may stop being developed any moment, and the versions I have already installed are the last ones. At least I have the source code…

Update. NPM has addressed this issue, and Azer won’t be able to unpublish his packages unless they are younger than 24 hours.

 

What’s Happening in the JavaScript Ecosystem

Lots of things are happening there. As of today it’s the liveliest software ecosystem. The last time I’ve seen such an interesting gathering was 15 years ago in Java.

The Past

Fifteen years ago Java developers were looking down on the JavaScript folks. It was assumed that JavaScript was only good for highlighting menus and making an impression that the Web site is current by displaying a running clock on the page. Mobile phones still had buttons with one digits and three letters. There were no App stores. Java was promising “Write once run everywhere”, but now we can see that JavaScript actually delivered on this promise.

Say, you are developing in the XYZ language and wrote tons of programs in this language over the last 15 years. During this time new versions of the XYZ were released. The hardware advanced and new versions of operational systems came about. And you decided to take your old XYZ program written in the last century and run it on the brand new iPhone 6 or Android. Voila! It works without changing a line of code! I don’t know about the XYZ language, but programs written in JavaScript 15 years ago still work on iPhones.

js

Having said that, writing in JavaScript was never a pleasant experience. Some people made fun of JavaScript. Making fun of Brendan Eich, who created JavaScript in 10 days, was popular.

Other people started creating multiple libraries and frameworks to lower the pain of writing in plain JavaScript and making it work in different browsers. Ten years ago there were a couple of hundred JavaScript libraries and frameworks. People were overwhelmed by the freedom of choice well explained by Barry Schwartz in this video. The ECMAScript was abandoned. HTML5 was not born yet. In short, Web development was not fun.

The Present

In 2016 the situation is drastically different:

— The ECMAScript (ES) standard is actively being worked on, and its new versions will be released annually. Last year the ES6 (aka ES2015) spec was released and ES7 will be released this year. Now the JavaScript language has classes, lambda expressions (a.k.a. arrow functions), predictable “this”, block scope, generator functions, promises, destructuring, spread and rest operators and more. Some hardcore JavaScript developers immediately started WTF-ing classes as being a lot worse than functions, but these discussions are as useful as arguments about where to put curly braces in the if-statements: on the same or on the new line. Classes are just a syntax sugar that doesn’t change the prototypal inheritance, but reading and writing code is much easier now.

— All major browsers support most of the ES6 syntax.

— Transpilers easily generate ES5 program from the ES6 code so you can deploy the ES6 code today in all browsers.

— Dozens of languages emerged allowing you to write code that gets converted int to JavaScript automatically. The best of the breed is TypeScript created by Anders Hejlsberg from Microsoft. In the past he also created C#, Delphi and Turbo Pascal.

— Tons of open-source JavaScript code are published in various repositories. The most popular repo is npmjs.org, which has more than 200K libraries, frameworks and useful utilities. By the way, npm literally killed bower, his former competitor.

— Google created a super-fast JavaScript engine V8. The Node.js framework allows you to write standalone applications that don’t require browsers. Node servers started to compete with the ones written in Java. Despite the single-threaded architecture of I/O, Node’s asynchronous processing allows handling tens of thousands client requests simultaneously.

— There are build automation tools (we use Webpack), which minimize and optimize the JavaScript code with the further bundling separate files together so browsers don’t need to make dozens of requests to the server to download that home page.

— The WebComponents standard prescribes how to develop custom HTML components. The Material Design principles explain how to develop nice-looking Web pages. Google implemented these principles in a library of custom components called Polymer. We already tried it in the real-world projects, and it works!

– HTTP/2, a major revision of HTTP will substantially speed up the client-server communications.

Libraries and Frameworks

The number of JavaScript libraries and frameworks is comparable to the number of presidential candidates in the Republican Party in the USA. Those (mainly enterprise) folks who want to get everything out of the box and are not afraid to sell themselves into slavery still use Ext JS. This is not an easy to master framework, but it has everything you need to develop back-office enterprise applications.

Developers who want a lighter framework that puts a structure on your app with navigation and data binding usually go with AngularJS 1.x or Ember. They would need to integrate third-party libraries for graphical components, grids, and a usual Twitter’s Bootstrap (to make the app usable on mobile phones and tablets), but it’s doable. Some people prefer the React framework from Facebook, but React is mainly about views, and you’d need to use some third-party libraries to build an app.

Those who don’t like prix fixe meals and prefer a la carte menus pick a bunch of small libraries each of which can do one thing well. They are ready to face the issues while trying to make these libraries work together. Such people charge higher rates and project managers keep their fingers crossed hoping that these developers won’t quit.

Fashion Trends

In this season every top model-developer entering a catwalk wears reactive accessories. Not that “reactive” is something completely new (even our grandmas liked messaging, pub-sub, and the observer-observable pattern), but in today’s asynchronous UI world, reactive is a must have. We need to give a credit to Microsoft (do people still hate it by default?) for beautifully designed reactive extensions, which in JavaScript world go by the name RxJS.

In the reactive world every component or service is implemented as a stream. Everything is a stream. You are a stream. I am a stream. A click on a button spits out the event as a next element of a stream. An HTTP request to a server returns a response as an element of a stream (promises had their 15-min of fame and are considered old fashioned these days). A piece of data pushed over a WebSocket connection is an element of a stream you can subscribe to. And there is a nice little twist to it: a subscriber can regulate the stream volume and lower the pressure if need be.

A year ago a team from Google decided to re-write their super-popular (1.1M devs) framework AngularJS. They started with creating a new language AtScript just for the new Anguar 2, but then invited the TypeScript team from Microsoft (can we start liking Microsoft, just a little bit?), and asked them to add some features to the TypeScript language. Microsoft folks kindly agreed, and Google wrote Angular 2 in TypeScript, which also became a recommended language for developing Angular 2 apps. Now the code of Angular 2 apps is easy to read and write even for Java and C# developers (see this). Needless to say that RxJS is embedded inside Angular 2.

Jokes aside, I really like the Angular 2/TypeScript/RxJS/npm/Webpack combo. During the last ten months I’ve been working with my colleague Anton Moiseev on the book “Angular 2 Development with TypeScript“. So far Manning published 300 pages of this book, and the remaining 150 pages are almost ready. The code faindz will lower the price of the eBook by 39%.

If you prefer to learn Angular 2 in a classroom setting, this year I’ll be teaching Angular 2 classes and my training/speaking schedule is published here.

The Bottom Line

My hat off to Brendan Eich for not over-engineering the language. JavaScript is getting a lot of traction and the demand for professional JavaScript developers will grow by leaps and bounds. Be there and stay current.