javascript

Building Large Scale Web Applications with TypeScript

Yesterday I had a pleasure to speak at .NET Developers Association meetup in Redmond, about building web applications with TypeScript.

Contents

0:00:00 – Intro (about me, and my work)
0:02:35 – Overview of JavaScript today
0:04:42 – voiceCmdr demo
0:06:55 – browser as a platform: rich UI experience and games (built with HTML/CSS/JS)
0:07:57 – TypeScript intro
0:09:25 – DEMO: TypeScript 101: strong typing, classes, inheritance, interfaces
0:26:15 – DEMO: Building web app with TypeScript, npm, bower, gulp, and dst
0:51:38 – ECMAScript 6
0:54:57 – DEMO: transpiling ES6 to ES5
0:57:56 – AngularJS 2
0:58:54 – DEMO: Angular 2 app written in TypeScript
1:06:08 – Angular 2 vs Aurelia
1:11:40 – FEEDBACK please!
1:12:00 – Q&A
1:20:56 – Recommended resources to get started with JavaScript and TypeScript

Video

Slides

Code

You can find demos from presentation on github.

You can also check out my voiceCmdr library that I blogged about a few weeks ago, and demo BooksLib website that is using it.

Summary

Thank you very much to everybody for coming. If you like (or not) my presentation please send me an email or leave a comment below. I really appreciate your feedback!


JavaScript Date: a Bad Part

We all know that JavaScript has some bad parts. However, one of them is usually forgotten, and skipped in most of “JavaScript Bad Parts” lists on the Internet. It is a Date object. You can have hard time working with it, especially if you want to support time zones. In this post I would like to outline quircks of Date in JavaScript.

Basics

In order to create a Date object, you just do:

var now = new Date();

This will create a date set to now.
If you want to create Date on specific day:

var year = 2015;
var month = 2-1; // February
var day = 27;
var now = new Date(year, month, day);

Here you encounter the first quirk: months are numbered from 0 to 11. January is 0, December is 11.

You can also specify hours, minutes, seconds, and milliseconds as additional parameters (no more pitfalls here):

var year = 2015;
var month = 2-1; // February
var day = 27;
var hours = 14; // 2PM
var minutes = 56;
var seconds = 37;
var milliseconds = 997;
var now = new Date(year, month, day, hours, minutes, seconds, milliseconds);

For more details about creating Date, check Date at MDN.

Formatting

If you want to display a date, there are a few available converters. Here are the most commonly used:

var date = new Date(2015, 1, 27, 14, 56, 37, 997);
console.log(date.toDateString());       // Fri Feb 27 2015
console.log(date.toTimeString());       // 14:56:37 GMT-0800 (Pacific Standard Time)
console.log(date.toLocaleDateString()); // 2/27/2015
console.log(date.toLocaleTimeString()); // 2:56:37 PM
console.log(date.toUTCString());        // Fri, 27 Feb 2015 22:56:37 GMT
console.log(date.toGMTString());        // Fri, 27 Feb 2015 22:56:37 GMT
console.log(date.toISOString());        // 2015-02-27T22:56:37.997Z
console.log(date.toJSON());             // 2015-02-27T22:56:37.997Z

Be careful with 3 and 4. Both return different results, depended on user’s machine settings and geographical location. This may cause UI issues (some date formats might be long).

Converters 5 and 6 are equivalent in all, most popular browsers. However toGMTString is deprecated.

Converters 7 and 8 are also equivalent. Moreover, toJSON use toISOString underneath to return result.

There is no significant issues with displaying Date, but there is no way to format it with custom format (e.g., ‘YYYY-MM-DD HH:mm’) like in C# or Java.

Alternative for formatting is Intl.DateTimeFormat object from ECMAScript Internationalization API. However, this API is not yet supported by older browsers, most of mobile browsers, and Safari (check browser compatibility on MDN).

Parsing

More tricky than displaying dates, is parsing them. There are two common ways to parse date from string:

var parsedDate1 = new Date("2015-02-27 22:56:37");
var parsedDate2 = Date.parse("2015-02-27 22:56:37");

First returns Date object, second – number 1425106597000 (milliseconds since January 1, 1970, 00:00:00 UTC).

There is one, very unpleasant detail in parsing:

Given a date string of “March 7, 2014”, parse() assumes a local time zone, but given an ISO format such as “2014-03-07” it will assume a time zone of UTC. Therefore Date objects produced using those strings will represent different moments in time unless the system is set with a local time zone of UTC. This means that two date strings that appear equivalent may result in two different values depending on the format of the string that is being converted (this behavior is changed in ECMAScript ed 6 so that both will be treated as local).

This means that date1 and date2 below (created from machine located in Seattle, WA) are different:

var date1 = new Date("2014-01-02");
var date2 = new Date("1/2/2014");
console.log(date1); // Wed Jan 01 2014 16:00:00 GMT-0800 (Pacific Standard Time)
console.log(date2); // Thu Jan 02 2014 00:00:00 GMT-0800 (Pacific Standard Time)

Recommended format for parsing is: YYYY/MM/DD – user local settings independent. It always assumes local timezone offset for date string given as a parameter.

var date1 = new Date("2014/01/02");
console.log(date1); // Thu Jan 02 2014 00:00:00 GMT-0800 (Pacific Standard Time)

Timezones

JavaScript Date object always assumes local timezone offset for the machine on which it is displayed. What is important: JavaScript Date does not support time zones, but only timezone offsets. This is a definition of both from Wikipedia:

A time zone is a geographical region where just about everybody observes the same standard time.
A time offset is an amount of time subtracted from or added to UTC to get the current civil time – whether it’s standard time or Daylight saving time.

In other words: time zone is constant (as long as government does not changed it) for some place (e.g., San Francisco) all the time, while time zone offset changes (usually, twice a year – this is what we call ‘daylight savings’).

To get timezone offset:

var myDate = new Date();
var timezoneOffset = myDate.getTimezoneOffset(); // result in minutes

The result is in minutes. Here is another quirk: timezones that are ‘west’ from UTC (offset = 0) have positive values (60 – 720), and timezones that are ‘east’ from UTC have negative values (-60 – -780). Thus, Pacific Standard Time (UTC -8:00), in JavaScript, has timezone offset 480, and Central European Time (UTC +1:00) has timezone offset -60.

One more pitfall: local timezone offset is always set depends on value of Date object. Thus, for Computer located in Seattle, WA:

var date1 = new Date(2015,1,20); // date in Pacific Standard Time (before timezone offset change)
var date2 = new Date(2015,2,20); // date in Pacific Daylight Time (after timezone offset change)
console.log(date1.getTimezoneOffset()); // 480
console.log(date2.getTimezoneOffset()); // 420

In this case your current ‘local’ timezone offset (for the time in which you are creating Date object) does not matter.

Even if you create Date object with date before the time change, and then you modify it to date after the time change – its timezone offset changes to reflect offset for the new (current) value:

var date = new Date(2015,1,20); // date in Pacific Standard Time
console.log(date.getTimezoneOffset()); // 480
date.setMonth(2); // change month so date is in Pacific Daylight Time now
console.log(date.getTimezoneOffset()); // 420

Moment.js

Moment.js is a JavaScript library designed to work on the client side (in browser), and on the server side (in node.js). It has a lot of functions to parse, display and manipulate dates. This makes dealing with dates less painful.

Moment Timezone – a library built on top of Moment.js – supports real time zones (not only timezone offsets). The data for Moment Timezone comes from the IANA Time Zone Database – most popular time zone database. New versions are released periodically as timezone laws change in various countries.

Consider using Moment.js and Moment Timezone in your application when you are doing more complex operations with dates. Especially when you want to support time zones.

Summary

It is really surprising that working with dates in programming is still causing a lot of issues. However, we are getting better at that. To get a comprehensive overview of date/time in programming language I recommend Date and Time Fundamentals by Matt Johnson. You can also check Matt Johnson’s blog. He blogs mainly about date/time in variety of environments. His article JavaScript Date type is horribly broken might be good supplement for this post.

To get a quick insight why dealing with time zones is very complex, check this video. It is also worth to check What Every Programmer Should know about Time.


voiceCmdr – voice commands in the Browser

voice recognition

Recently I discovered Web Speech API. I was already talking to the browser using Google Hangout and Google Translator, but I have never thought about adding voice support to my own website.

I did some research, and I found a demo. Based on that I put up simple demo website (say: “show website blog”, and it will take you directly to the sub page that can be also approached with 3 mouse clicks). For now speech recognition works only in Google Chrome and Safari. In Chrome it is not SpeechRecognition API, but webkitSpeechRegognition API. I hope, in the near future, other browsers will also implement it. Especially Spartan, which is integrated with Cortana.

I noticed that while the API is flexible, it is not easy to use. I think, for most common scenarios, developer would like to be able to add commands associated with function callbacks, and control recognition state with start/stop actions.

I created a JavaScript library voiceCmdr. It is a single .js file without any dependencies. You can install it with npm or bower (check README on github).

You can add commands:

voiceCmdr.addCommand("go home", function () {
  // go to home page
});

Callback function can have parameter, which is everything you said after command. E.g.:

voiceCmdr.addCommand("search", function (param) {
  // search for phrase specified in param
});

You can also remove commands:

voiceCmdr.removeCommand("go home");

In order to start listening for commands:

voiceCmdr.start();

To stop listening:

voiceCmdr.stop();

You can also invoke listening for single command:

voiceCmdr.getCommand();

Check examples, and be aware that Web Speech API works only through http, and https (it will not work if you open static html file). The easiest way to run server is to use python SimpleHTTPServer:

python -m SimpleHTTPServer 8080

This can also go another way (by browser talking to you) with Web Synthesis API.

I am curious what do you think. Are we ready for voice commands in the browser? Are you concerned about your privacy (check Scott Hanselman’s tweet)?


Web Development tools you need to know by the end of 2014

npm, bower, grunt, gulp, yeoman

If you are web developer you have probably heard about some (or all) of these tools:

  • npm (Node Packaged Modules) – package manager for node.js
  • Bower – package manager for the front-end
  • Grunt – task runner for front-end
  • gulp.js – task runner created under inspiration of grunt (I blogged about gulp)
  • Yeoman – scaffolder that helps to start new projects by generating (scaffolding) files structure and content based on the best practices

You do not have to master all of them, but at least be aware of their functionality, and what they offer.

I will not dig into these tools here, because there are tons of resources online. Good point to start is Scott Allen’s talk from NDC 2014: Node.JS Tools For Front-End Developers (an overview of mentioned tools), and John Papa’s article: Get Up and Running With Node and Visual Studio (demo that take advantage of all tools mentioned above).

If you are interested in other web development tools, check Front-end Tooling Workflows by Addy Osmani.


Two great books about JavaScript

Recently I read two great books about JavaScript: JavaScript: The Good Parts and Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript. Both are not for beginners, but rather programmers who know some Object Oriented language (e.g., C#, Java or C++).

JavaScript: The Good Parts

JavaScript: The Good Parts - cover
Written by the “God Father of JavaScript”: Douglas Crockford. This book is an overview of JavaScript language features that are different than in Object Oriented programming languages, such as C# or Java. Additionally, there is an overview of the good, and the bad parts of the language. What to avoid, and how. You can read it in a week (~200 pages).

In addition to JavaScript Good Parts, I recommend you to watch Crockford on JavaScript (mirror). You will learn not only about JavaScript, but also about the history of programming languages. There is also JavaScript the Good Parts course by Douglas Crockford on Pluralsight. This course is focused only on JavaScript though.

Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript

Effective JavaScript - cover
I like this book even better than “The Good Parts”. It contains very good examples that show specific aspects of the language. These examples combined with associated explanations makes this book clear and very informative for me. What I like especially was the structure: short 68 problems with explanation, analysis, and examples. Also, not very long (~200 pages). If you can choose only one of the books described in this post, read this one.

Other JavaScript books

I would be very happy to hear from you other JavaScript books that are worth (or not) reading. So far, besides mentioned books, I heard good things about:

Can you recommend some of them? Share your opinions in comments.