Monday, October 3, 2016

Debugging Touch Events on the Desktop

It can be a pain in the behind to debug touch events when developing your web application on the desktop. But I found this great setting in Chrome that makes it a whole lot easier. Just put this into the browser:

chrome://flags/#touch-events

If you set the value to "enabled" it will then emulate touch events whenever you are emulating a touch device. How do you emulate a touch device, you ask?

To emulate a touch device open up developer tool (F12) and click on the "Toggle Device Toolbar" button. At the time of this writing it's in the upper left corner of the window (it seems to move around with each new release so you may have to hunt for it).


When you turn this feature on it shows how the web page would look on that device, allows you to rotate the device, and allows you to choose from multiple devices including iPhone and Nexus or even define your own device.



When you have both of these features enabled you will start getting touch events instead of mouse events. To switch back to mouse events just turn device emulation off. You can leave the touch-events flag on, it won't hurt anything.

Code hard!

Thursday, August 25, 2016

HTML5 Canvas DrawImage Artifacts

I'm working on an HTML5 canvas game that requires smooth scrolling of images across the screen. The coordinates of the images are real numbers, not integers. The canvas can handle real number coordinates just fine and antialiases everything to make it look smooth. The problem is that it also sometimes produces some weird artifacts to be drawn.

What do I mean by artifacts? Artifacts are pixels that are drawn that you don't expect. In my case, for example, I have an image that has a significant amount of transparent pixels. When it's drawn at particular locations thin gray lines get drawn in some of the space where it should be transparent. It's not a lot, but it's noticeable.

So what can you do about it? There are a couple things, but they have their disadvantages. For one thing you can convert all of your coordinates to integers. One way to do this is with a little JavaScript trick; binary "or" the value with 0.

var x = 1.67;
x = x | 0; // x is now 1

That eliminates the artifacts because the images are drawn on whole pixel boundaries, so there's no need for the canvas to smooth out the image. The problem is that it makes your animations really choppy, especially if you have a lot of images scrolling next to each other.

Another thing I tried was to use Math.round() instead of just lopping off the fraction. I figured that would reduce the amount of choppiness. Unfortunately it didn't make much of a difference.

var x = 1.67;
x = Math.round(x); // x is now 2

But wait, there's one more. The canvas context has an imageSmoothingEnabled property you can set to true or false. By default it's true. I found that when you set it to false it's basically the same as using Math.round() above. It forces your images to be drawn on whole pixel boundaries. Which also produces choppiness.

context.imageSmoothingEnabled = false;
context.mozImageSmoothingEnabled = false;
context.webkitImageSmoothingEnabled = false;
context.msImageSmoothingEnabled = false;

So now we're right back where we started. In the end I decided not to use any of these methods and just stick with the occasional artifact being drawn. It looks crappy, but it only seems to happen at certain screen locations. In my case having smooth animations was far more important than the occasional artifact.

I think in most cases the choppiness wouldn't be such an issue and one of these techniques would work. It's up to you to determine what looks best. I would go with using imageSmoothingEnabled property because then you don't have to add any extra code to convert to an integer. Let the system do the work for you.

Code hard!

Saturday, May 7, 2016

Testing TypeScript Modules with Jasmine

In my previous post I talked about using TypeScript/ES6 modules. I have been thinking about making the transition from namespaces to modules, but there were a few things I needed to work out first. First of all how to load them (native ES6 support isn't widely available at the time of this writing). In the previous post I talked about using a library called Require1k (http://requirejs.org/) as the module loader. As the name suggests it is only 1kb in size yet provides the basics you need for CommonJS module loading. So far it does everything I need.

The next thing I needed to work out was how to package up my application when it was ready for release. In that post I also talked about using WebPack in Node.js to combine and minify the application modules.

The final thing I needed to work out was how to get my Jasmine (http://jasmine.github.io/) unit tests to run against modules. This was giving me a lot of trouble; it's not as easy as you might think. Jasmine was built in such a way that it expects all of your files to be loaded using script tags, then it runs when the page onload event fires. Unfortunately when using a module loader things don't happen that way. The module loader doesn't load your modules until after the page is loaded.

So for the remainder of this post I'll show how I got my Jasmine tests to run using the Require1k module loader. Although I'm using a specific module loader there shouldn't be any problem using the same principles for any other CommonJS module loader library as they most all work the same way.

Creating the Unit Tests


The first thing we need to do is create unit tests. I won't go into how to write Jasmine tests. There are plenty of good examples on their web site. The only difference is that you will need to use import statements to reference the modules you want to test.

For example, say you want to test module1.ts. Then your unit tests might look something like this.

/// <reference path="../scripts/typings/jasmine/jasmine.d.ts" />
import * as Module1 from "./module1";
describe("When testing module1", () =>
{
    it("should be true when something happens", () =>
        expect(Module1.something()).toBeTruthy());
});

First we have a reference to the Jasmine type definition file (because as TS programmers we like to have better tooling and autocompletion). Then we import everything from module1. Then we define the Jasmine specs for the unit tests. It's that simple ;-).

One important thing to point out here: your unit tests are modules too. Once you decide to use modules everything needs to be a module. Our unit tests need to load the modules they test, therefore they have to be modules for the module loader to pick up the imports and load them.

The Bootstrap File


Now we need a bootstrap file. This is the main file that gets things going. We will call this file unit-tests.ts.

declare function require(s: string): void;
 
require("./module1.spec");
require("./module2.spec");
 
jasmine.getEnv().execute();

The first thing we did was to declare the require function. This is the function defined by the Require1k library (or any other library for loading CommonJS modules) to load a module file. Without this we would get errors from the compiler because it doesn't know what "require" is.

Next we use require to load all of the unit test modules. In this case we have unit tests for two different modules.

I like to name my unit test files with the name of the module it's testing and a ".spec.ts" extension. This way you know exactly which module it's for and you know it's a Jasmine test file (Note: unit tests are known as specs in Jasmine).

The last line is necessary to tell Jasmine to start running the tests. As I stated above, Jasmine will look for any unit tests and run them on page load. But since this is all happening after page load we have to explicitly tell it to run again.

You might be asking yourself: why not use import statements to load all of the unit test files? That's a valid question. The unit tests are modules, I said so previously. The answer is: because nothing is being exported from the unit test modules. All they do is define Jasmine specs. Therefore if you tried to import them the TypeScript compiler would see there's nothing being exported and just skip it. Then your unit tests wouldn't load and you would be wondering what's going on (not that I'm speaking from experience or anything like that).

The Host File


The final thing we need to do is set up the host HTML file to run the unit tests. It will have all of the files for jasmine, of course. Then it will need the script tag for Require1k.

<link href="../Content/jasmine/jasmine.css" rel="stylesheet" />
<script src="../Scripts/jasmine/jasmine.js"></script>
<script src="../Scripts/jasmine/jasmine-html.js"></script>
<script src="../Scripts/jasmine/boot.js"></script>
 
<script src="require1k.js" data-main="./unit-tests"></script>

The "data-main" attribute tells Require1k what the main or start file is. In this case unit-tests.js which we created above. This will define the starting point of the module loader. From there it will load the unit test modules which will in turn load the modules they are testing.

Conclusion


The trick to testing external modules with Jasmine is to have a single bootstrap file that loads all of the unit test files and to tell the module loader where to find it. Then the key to making it work is to tell Jasmine to run again after all of the tests and modules have been loaded.

Switching from internal namespaces to external modules in TypeScript requires a whole new way of looking at things and some new ways of doing things that you're not used to. You just have to learn a few new tricks to get it to work across the board from your source code to your unit tests.

I think in the end using modules is the way of the future for TypeScript, and JavaScript. Once ES6 is fully supported by all browsers and able to provide native module loading things will be a lot easier and modular JS will become more popular.

<jmg/>

Wednesday, April 6, 2016

Packaging Web Apps with Node.js

There comes a time when you're at the end of developing your awesome TypeScript/JavaScript web app that you need to think about releasing it into the wild. If you've been using good programming practices you should have split your app into multiple files to make it easier to manage and maintain. Only problem is, it's not a good practice to serve up a ton of files when the user runs your app. The best practice in this scenario is to package up your JavaScript files into one file and only serve that one file.

In this post I will show you how to use TypeScript/ES6's module loading system and Node.js to make it easy to package your web app's files into one file for release while allowing you to develop without packaging. We will use TypeScript's module system to set up file dependencies. Then we will use Require.js to load those modules in the browser. Finally we will use Webpack to package up all of the files into a single JS file and compress it for release.

Prerequisites: I'm assuming you know TypeScript and Node.js basics, but even if you don't you should be able to understand the concepts and use them as a jumping off point to learn more.

The Modules


First of all lets look at how external modules work in TypeScript/ES6. For this example we are going to create three separate TS files, each of which depends on the next one. Two of the files will be modules and the other will be the main application file.

The first file module2.ts exports a class named MyClass2 with a public method getText().

export class MyClass2
{
    public getText(): string
    {
        return "Hello from module 2";
    }
}

Nothing special yet. We just have a class with a method.

The next file is module1.ts. It is a bit more interesting.

import * as module2 from "./module2";
 
export class MyClass1
{
    public getText(): string
    {
        let c = new module2.MyClass2();
        return "Hello from module 1 " + c.getText();
    }
}

At the top of the file we import our module2 module that was defined in module2.ts. Now this file depends on module2.ts. This allows us to use the exported members of module2.ts in module1.ts. This syntax follows the ES6 standard for importing modules.

Next we define the contents of module1. We export a class called MyClass1. In the getText() of this class it creates and instance of MyClass2 from module2 then calls its getText() method and concatenates the messages together.

That's how we do external modules in TypeScript and ES6. Pretty simple, right?

Now we need a main app file for our starting point, which in this case is app.ts.

import {MyClass1} from "./module1";
 
namespace WebpackModules
{
    export class MyApp
    {
        constructor()
        {
            let c1 = new MyClass1();
            var el = document.getElementById('content');
            el.innerText = "MyApp started " + c1.getText();
 
        }
    }
}
 
var app = new WebpackModules.MyApp();

We begin with an import of module1.ts. Now this file depends on module1.ts and by association module2.ts. Notice that the import is a little different from the previous one. Instead of importing everything from module1.ts and assigning a name for the module, we are only importing the MyClass1 class.

Next we wrap the MyApp class in a namespace just because this is what I would do in a real app to keep the global scope clean. If you're not familiar with it, namespace is the new keyword to create internal modules in TypeScript and is equivalent to the old keyword of module.

Inside the namespace we export the main application class, MyApp, so we can use it outside of the namespace. Inside the constructor is where we use the MyClass1 that we imported. We create a new instance of MyClass1, then call getText() on that object and output it to the web page.

The Script Tag


Now we need to set up our web page and get a module loader that can load the modules for us. At this time most browsers don't support the loading of modules using the ES6 specification. Therefore we are going to have to use something else. A well known module loading framework is RequireJS (http://requirejs.org/). So let's use that.

In order to use RequireJS we need to tell the TypeScript compiler which kind of package manager we are using. RequireJS implements the AMD standard so we must tell the TS compiler to use AMD. If you're in Visual Studio you can change it in the project properties. Otherwise change it in the tsconfig.json file ("module": "amd"). The TypeScript compiler will output the correct code that works with the package manager of your choice.

In the html file we only need one script tag that references the require.js file.

<script src="../Scripts/require.js" data-main="app"></script>


Notice that it has a data attribute called data-main. This is where you tell it what file is your entry point. In this case it's app.js, or just app (you don't need to specify the file extension). When the web page is loaded Require will load app.js first, then fulfill all of the imports specified inside the application's modules (module1.js and module2.js).

At this point the application is running and it is loading all the files separately. This great for our development environment. If all our files were packaged up in development it would make it a lot harder to debug.

Packaging the App


When it's time to release the app we need to package it up. For this we will be using a Node package called Webpack. You can easily install it using "npm install webpack -g". Then you can execute it from the command line telling it where your entry point file is and where to save the packaged file.

$ webpack ./src/app.js ./app.package.js


Here we tell it to start with app.js and save the result to app.package.js. Webpack will go through all of the imports just like Require did and load all the dependencies then save all of the code in the correct order in the output file along with any code it needs to bootstrap the app.

At this point you can change the require.js script tag to set data-main="app.package.js" and the application should run. Congrats, you now have a packaged up web application.

One thing to note about using Require, it's a very comprehensive library and therefore not a small file. The minified version is about 85kb. So you're making the user download 85kb just to run your app. If you don't need all of that functionality there is another, much smaller option, Require1k.

Require1k is a minimal library for loading CommonJS modules. If all you want to do is use modules in a web application it's perfect. And, as you can tell from the name, the file is only 1kb. That is a BIG difference. If you can use it instead you probably should.

To use Require1k we will need to change the TS compiler module type option to CommonJS ("module": "commonjs"). Other than that it works exactly the same. The script tag would look like this now:

<script src="require1k.js" data-main="./app"></script>


The only thing that changed was the name of the source file. From here we can use webpack just as we did before and everything should run, but with only 1k of bootstrap code.

Bonus Points: Minification


OK, all of our JS files are packaged up into one file. That's great but it could be better. We could minify the file to make it as small as possible. To do that we can use a Node package called Uglify. Install it using "npm install uglify-js -g".

It's very simple to use. Just point it at the file you want to minify.

$ uglifyjs ./app.package.js -o ./release/app.js -c -m


Use the -o option to specify where to save the minified file to. The -c option tells it to compress. The -m option tells it to mangle names which will rename everything it can to single letter names for more space savings.

Conclusion


Here we have seen how to use external modules in TypeScript/ES6 and how to use Require to load modules in the browser. Then we learned how to use the Node webpack tool to help us package up our TypeScript app for release while keeping them unpackaged for development. Then we seen how to use uglify to compress our application's code.

Knockout in Chrome Web Apps (Yes!)

In a previous post I lamented on the fact that you can't use Knockout when creating a Chrome web app. The problem is that Knockout doesn't play well with Chrome's content security policy (CSP) because its binding engine uses "new Function" to parse bindings. This could allow someone to inject malicious code into the Chrome app which has access to low level resources that normal HTML5 apps don't.

After looking around though I came upon a solution to the CSP problem in Knockout. It seems I wasn't the only one with the problem. I found that Brian Hunt created a binding provider for Knockout that is CSP compliant. The project, called Knockout Secure Binding (KSB) can be found on GitHub. It is a replacement for Knockout's built in binding provider.

KSB is not a complete replacement though. It is limited in the kind of bindings you can create. Since it can't use "new Function" to parse bindings you can't create more complex bindings such as passing parameters into functions, and only a subset of JS expressions are available. But these limitations can easily be resolved by being more mindful of your bindings.

For example, say you have a binding for a "like" button that sets a certain thing as being liked. It calls a function in your view model called "like" and passes in the thing to like and true or false.

<button data-bind="click: like("knockoutJS", true)">Like</button>
<button data-bind="click: like("knockoutJS", false)">Dislike</button>

This won't work when using KSB because it doesn't support passing parameters to functions. You will need to rewrite the binding so it doesn't have to pass parameters.

<button data-bind="click: likeKnockoutJS">Like</button>
<button data-bind="click: dislikeKnockoutJS">Dislike</button>

Now the expression is moved back into the view model into functions called likeKnockoutJS and dislikeKnockoutJS. The downside is that this is going to require your view model to have a lot more functions in it, but your bindings will probably be a lot cleaner in the end.

KSB supports most any logical expression including comparison and mathematical operators, so you can perform some basic binding expressions.

<button data-bind="visible: !knockoutJSLiked())">Like</button>
<button data-bind="visible: knockoutJSLikeCount() > 0">Dislike</button>

Here the like button is visible only when the knockoutJSLiked() function does not return true. The dislike button is only visible when the knockoutJSLikeCount() function returns a value greater than zero.

To use KSB you just need to tell Knockout to use it as your binding provider before applying your bindings. You create an instance of a ko.secureBindingsProvider passing in the options you need and set that as the ko.bindingProvider.

let options = {
    attribute: "data-bind",        // default "data-sbind"
    globals: window,               // default {}
    bindings: ko.bindingHandlers,  // default ko.bindingHandlers
    noVirtualElements: false       // default true
};
ko.bindingProvider.instance = new ko.secureBindingsProvider(options);
ko.applyBindings(this.viewModel);

For more info on using KSB see the GitHub page.

In my app (PowerChord) I had to do some reworking to get my bindings to work with KSB. I also had to rewrite some components to make them work, which was probably a good thing because they were a bit convoluted. KSB forced me to write my components the way they should have been written instead of trying to use shortcuts with complicated bindings in my view.

Overall I'm very pleased with KSB and highly recommend it if you are writing a Chrome web app or need to implement the CSP and want to use Knockout as your binding framework (which I highly recommend).

Thursday, March 31, 2016

Empty TypeScript Files When Debugging

When developing TypeScript web apps in the browser, it uses a map file to load the TypeScript file that maps to a JavaScript file. You'll usually see something like this at the bottom of your JS files.

//# sourceMappingURL=app.js.map

Inside that map file is a bunch of JSON, including the name of the TS files that it maps to.

"sources":["app.ts"]

This causes the browser to go out and download the TS file so you can debug it in the browser developer tools.

Seems like every time I start a new project I run into the same problem. I go to debug my code, I open up the TS file in dev tools and it's empty. It takes me a minute then I say, "Oh yeah, I remember now!".

The problem is that IIS doesn't know how to serve TS files, so you have to tell it. All you have to do is go into the web.config file and add the following inside the system.webServer section:

  <system.webServer>
    <staticContent>
      <mimeMap fileExtension=".ts" mimeType="application/x-typescript" />
    </staticContent>
  </system.webServer>

This tells the server that whenever it sees a file extension of ".ts" that it's a TypeScript file. Now if you go back the browser and refresh you'll be able to see the contents of the mapped TS files.

Note: you can do this for any other file types IIS doesn't know about, such as audio/ogg. Any time the browser complains about not finding a file and you know the path is correct, it's probably because of the Mime type not being recognized.

Also note that you can do this within IIS too. Go to your website, open "Mime Types"and click Add to add it.

Tuesday, March 22, 2016

Creating a Node.js REST Service with TypeScript

In my last post I talked about the basics of creating a Node.js server app using TypeScript in Visual Studio. In this post I'll expand upon that to show how to create a RESTful web service that exposes an API to access CRUD operations for a "todo" web app.

Body Parser Middleware


We'll start where we left off in the previous post. In that post we added the Express package using npm. For this app we also need to add the Express body-parser module. This module is a middleware component for Express that parses the body of HTTP requests so we can get data that has been sent via a POST request. To add it right click on "npm" in the project tree, select "Install new npm Packages", then search for "body-parser" and install it.


Now we need the type definition file for body-parser so we get intellisense in our TypeScript files. We'll have to get that from the Node command line using "typings". Make sure you're in the project folder then execute the following:

> typings install body-parser --ambient --save

Now we can start to write our main module, app.ts and include body-parser.

import express = require("express");
let app = express();

import bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: true }));

First we import express and create our app. Then we import body-parser and tell our app to use its urlencoded middlware component. This middleware takes incoming POST requests where the body uses x-www-form-urlencoded format and parses the form data into name/value pairs which can be accessed through the request.body object. We'll see more about that later.

The Data Model


Before we go any further we need to define our todo item model. So let's create a folder in our project called models and add a new TypeScript file called todoModel.js.

export interface ITodoItem
{
    id: number;
    name: string;
    created: Date;
}

let nextId = 1;

export class TodoItemModel implements ITodoItem
{
    public id: number;
    public created: Date;

    constructor(public name: string)
    {
        this.id = nextId++;
        this.created = new Date();
    }
}

Inside there we define an ITodoItem interface, then we define a TodoItemModel class that implements it. I like to have an interface for each model so that we don't always need to use the class, especially if we're getting objects from JSON.

Notice that the interface and class are exported so we can use them outside of the module. Notice also the variable named nextId. This is used in the constructor to create a unique ID for each todo item that is created. We don't want this variable to be visible outside of the module so we don't export it.

The Data Repository


Now we need a repository to save our todo items in. Let's create a folder called repositories and add a TypeScript file called TodoItemRepo.ts.

import models = require("../models/todoModel");

export interface ITodoItemRepo
{
    add(item: models.ITodoItem): void;
    remove(id: number): models.ITodoItem;
    findById(id: number): models.ITodoItem;
}

export class TodoItemList implements ITodoItemRepo
{
    private list: models.ITodoItem[] = [];

    public add(item: models.ITodoItem): void
    {
        this.list.push(item);
    }

    public remove(id: number): models.ITodoItem
    {
        for (let i = 0; i < this.list.length; i++)
        {
            if (this.list[i].id === id)
            {
                return this.list.splice(i, 1)[0];
            }
        }

        return null;
    }

    public findById(id: number): models.ITodoItem
    {
        for (let i = 0; i < this.list.length; i++)
        {
            if (this.list[i].id === id)
            {
                return this.list[i];
            }
        }
        return null;
    }
}

First we import our todo item model, then define an interface for our todo item repository. We need a way to add, remove and find items in the repository. Then we implement a repository for that interface called TodoItemList that merely stores the items in an array. In a real app our repository would probably interact with a database, but that's beyond the scope of this post.

Defining the Routes


Now that we have our model and a place to store our data we can create our routes. First thing we want to do is create a folder called routes and create a new TypeScript file called todoAPI.ts. This module will hold all of our routes and the implementation of those routes. By placing them in their own file we keep them out of our main file app.ts to keep it clean.

import express = require("express");
import models = require("../models/todoModel");
import repos = require("../repositories/todoItemRepo");

let todoList = new repos.TodoItemList();

export function initRoutes(app: express.Express): void
{
    app.get('/todo', list)
        .post("/todo", create)
        .get("/todo/:id", getById)
        .put("/todo/:id", update)
        .delete("/todo/:id", del);
}

function list(req: express.Request, res: express.Response): void
{
    res.status(200).json(todoList);
}

function create(req: express.Request, res: express.Response): void
{
    todoList.add(new models.TodoItemModel(req.body.name));
    res.status(200).json(todoList);
}

function getById(req: express.Request, res: express.Response): void
{
    let id = parseInt(req.params.id);
    let item = todoList.findById(id);
    if (item)
    {
        res.status(200).json(item);
    }
    else
    {
        res.status(400).send("Item not found: " + req.params.id);
    }
}

function update(req: express.Request, res: express.Response): void
{
    let id = parseInt(req.params.id);
    let item = todoList.findById(id);
    if (item)
    {
        item.name = req.body.name;
        res.status(200).json(item);
    }
    else
    {
        // Bad request
        res.status(400).send("Item not found: " + req.params.id);
    }
}

function del(req: express.Request, res: express.Response): void
{
    let id = parseInt(req.params.id);
    if (todoList.remove(id))
    {
        res.status(200).json(todoList);
    }
    else
    {
        // Bad request
        res.status(400).send("Item not found: " + req.params.id);
    }
}

First we import the model and repository modules. Then we create a new TodoItemList to hold our items. Next is the only function that will be visible outside of the module, initRoutes(). This function takes our app that we created in app.ts and adds the routes for our API to it.

All of the routes start with "/todo" and a few have "/:id" appended. By placing a colon at the beginning of a route part it tells the express router that this is a parameter. All route parameters will be map it to the request.params object. So in this case we should be able to access request.params.id.
Each route is mapped to a function that is defined in the module. Note that none of the handler functions are exported. They don't need to be because we are setting up the routes inside the module.
  • The list() function merely returns the todo list object.
  • The create() function first gets name of the new todo item from the request.body object using request.body.name (The body-parser middleware put it there for us). Then it creates a new instance of a TodoItemModel and adds it to the list. Finally it returns the updated list.
  • The getById() function gets the id parameter from the request.params and returns the matching todo item. If one isn't found it returns a 400 HTTP status.
  • The update() function gets the id of the item to update from the request.params and the new name of the todo item from the request.body object and updates it. Then it returns the item.
  • And finally the del() function gets the id of the item to delete from the request.params and removes the item from the list then sends back the updated list.

Starting the Service


That's it for our todo API! Now we need to go back into our main file, app.ts and tell it to use our routes and start the service. We add the following to that file:

import todoApi = require("./routes/todoApi");
todoApi.initRoutes(app);

let port = 8080;
let server = app.listen(port, () => console.log("Listening on port " + server.address().port));

First we import our todoAPI module, then call its initRoutes() function passing in our application. Then lastly we start the service by calling app.listen().

Let's go run it now and test it out. From the Node command line we start the service.

node app

We should get the message, "Listening on port 8080" if all went well. Now we need to test it.

Testing the API


In order to test our API we'll need a tool to test REST web services. We're not creating the front end as part of this post so we'll need another way to test it. I like to use the Postman extension in Chrome (http://www.getpostman.com/). It allows you to specify any REST verb as well as specify parameters in the body of the request.

First let's add a todo item. To do that we will set the verb to POST and use the URL: http://localhost:8080/todo. We also need to specify the todo item name in the body. We need to use x-www-form-urlencoded as the body type.



Now click the Send button and it adds a new item named Task1. It also returns the todo list which we see in the response body. That means it worked. Now let's test some other routes.

  • Set the verb to GET and call http://localhost:8080/todo. This will hit return the list of all items.
  • Set the verb to GET and call http://localhost:8080/todo/1. This will get the item with the id of 1.
  • Set the verb to PUT, add a name parameter to the request body, and call http://localhost:8080/todo/1. This will change the name of the item with id of 1.
  • Set the verb to DELETE and call http://localhost:8080/todo/1. This will delete the item with id of 1.

In this way you can play around with the todo service API adding, removing and changing todo items.

No we have a working web service with CRUD operations for managing a list of todo items. From here we could write a front end app that consumes these APIs. Look for a future post to implement that.

<jmg/>

Friday, March 18, 2016

Using TypeScript with Node.js

I've been putting off learning how to write a Node.js app long enough. So I decided that I wanted to learn by writing a REST web API service. I also wanted to write it using TypeScript so I could get static typing and intellisense to make it easier to learn.

I looked at a lot of tutorial out there and they all want to over complicate things. So I thought I would boil the process of creating a Node.js RESTful web API service and using TypeScript as the programming language. I'm using Windows and Visual Studio 2015 for this tutorial.

First thing you need is to install Node.js of course. That's not too difficult. Go to https://nodejs.org/ and download it.

You're also going to want to make sure you have the latest version of TypeScript for Visual Studio. Go to Tools > Extensions and Updates and search for TypeScript and install it.

Another great tool for VS that is going to make your life a whole lot easier is Node.js Tools for Visual Studio. NTVS is a free, open source plugin that turns Visual Studio into a Node.js IDE. You can also install it from Extensions and Updates.

Now let's create a project for our Node.js app. Assuming you've installed NTVS you can create a new project using one of the project templates that NTVS installed. For this example I used Blank Node.js Console App project.


Now that we have our project we need to define what npm packages our app depends on. We want to use Express (http://expressjs.com/), which is a web application framework that makes it easier to handle HTTP requests and responses. It also makes it easy to insert any middleware you want in your HTTP handling pipeline, such as logging and parsing message bodies. It's a really great framework for creating web apps.

To install it right-click on the "npm" item under the project in solution explorer and select Install New npm Packages. Search for express and install it. Now you'll see it in your list of installed packages.


Next we want to get the TypeScript type definition files for Express so we have intellisense. Unfortunately I couldn't find any way to do this from inside VS, so we're going to have to go to the node command line to do that. First thing we need is a package to help manage type definitions. There is a npm package called Typings for that (https://github.com/typings/typings). Install it from the command line like so:

> npm install typings --global

Now we can use Typings to fetch type definitions for our project. So first navigate to the project folder.

> cd \lab\MyWebApi

Then install all the type defs we need. Express uses the following typings:

> typings install dt~express --global --save
> typings install dt~serve-static --global --save
> typings install dt~express-serve-static-core --global --save
> typings install dt~mime --global --save

[Update: 2016-08-15] Previously this was using the --ambient parameter. However, this is now deprecated, use --global instead. Also, you must now prefix the module names with "dt~" so it knows the source is the Definitely Typed library.

This should have added a typings folder under our project folder with all of the typings. It also created a main.d.ts file in there. That's the only file we need to add to the project, so in VS go and include that file in the project.

That's it for setup. We are now ready to code. Open up the app.ts file and remove anything that's already in there. Then add the following:

import express = require("express");
let app = express();

This imports the express module so that we can use it. Then we use it to create a new express app and assign it to the app variable. Now we can set up some routes for our RESTful web API service. Let's add a GET route and set the route to "/api".

app.get("/api", (req, res) =>
    {
        res.status(200).json({ message: "api GET called!" });
    });

Here we are telling our app to watch for GET requests on the path /api and run the handler function when we get one. The handler function gets two parameters, the request and the response objects. Our handler function first writes to the response an HTTP status code of 200 (OK) then tells it to return some json. Pretty simple! In a real app we would get some kind of real data, but for now we're just making sure it works.

Now we need to start the server listening for requests. For that we add:

let port = 8080;
app.listen(port, () => console.log("Listening on port " + port));

This will start the server on port 8080. When it's ready it will display the message logged from the callback function. Now we can run it and see if it works. To start the app go back to the node command prompt and enter:

> node app

You should see the message "Listening on port 8080". Now open a browser window and go to: localhost:8080/api. You should get {"message":"api GET called!"}. That's it, you now have a RESTful service running in Node.

Now we can add any of the other REST verbs we want our service to support. Express supports all of the REST verbs. For example, if we want to add a handler for POST we can add the following:

app.post("/api", (req, res) =>
    {
        res.status(200).json({ message: "api POST called!" });
    });

To test anything other than GET requests you're going to have to use a Web API testing tool like Postman (http://www.getpostman.com/). I highly recommend it for testing web APIs.

Those are the basics for creating a RESTful web API service using Node.js in Visual Studio with TypeScript. Next time I'll show how to make the web service more modular so it's easier to maintain larger services.

Thursday, February 25, 2016

Knockout in Chrome Web Apps (Not!)

Edit: I found out how to get around this problem. View this post.

My love of Knockout.js just took a big hit. I recently converted one of my old applications to TypeScript and in the process I was going to try to turn it into a Chrome web app.

Short story: Chrome web apps don't like Knockout.

Long story: I've created a couple other Chrome web apps in the past but they are the kind that are only links to the app on my website. There is another kind that is actually is able to run in its own window like a real application and can be run on other devices like Chromebooks. That's what O was trying to do.

So I got my app working and used Knockout to do some data binding. Since my app uses local storage I also had to convert it to use Chrome's version of local storage. If you're building one of these Chrome apps you must use their local storage, not the HTML5 kind. Since I wanted my app to run both in the browser and as a Chrome app I had to do a lot of work to make it use the correct storage based on the context.

After I got everything working I tried to test my Chrome app and that's when things went south. Apparently Chrome apps have a strict content security policy (CSP) which doesn't allow you to use things like eval() or new Function(). This is because a Chrome app has access to more resources than a normal web app running in your browser. Therefore someone could do potential harm to your computer if they were able to access it using one of those runtime evaluation methods.

I found out real quickly that Knockout doesn't work with CSP because it does have some runtime evaluation code. Ugh! A bunch of work down the drain. Well, I shouldn't say it was all a waste of time. I did learn to make my apps work in different contexts, how Chrome local storage works, and how to set up a Chrome web app.

I'm just disappointed that I can't use Knockout if I want to have my apps available in the Chrome web store. I've committed heavily to Knockout for my web apps. I think it has a great balance between enough functionality and being too opinionated, like say Angular is. I really enjoy using it.

I guess the search is on for a new MV* framework that isn't too hard to learn, isn't too opinionated, and works in Chrome web apps. Maybe it's back to using Angular, or maybe it's something else, I don't know. I'll keep you posted.

Monday, February 8, 2016

Knockout with TypeScript - Embedded View Models

In my last post about Knockout and TypeScript I talked about interacting with observable arrays. This time we'll take a look at using embedded view models.

Knockout uses the concept of view models at its core. View models link to the view to provide data binding and functionality. There are times when you may want a more complicated structure for your view model. You may want to have child view models inside of view models so you can partition your application more effectively. So today I'll talk about how you do that.

What I sometimes like to do is create a master view model for my application in general, and then add view models underneath it for specific parts of the application. Say we have an application with two different views that have different data. In this example one view shows a list of favorite books and another shows favorite authors. You could have one view model with everything in it, but you can get a problem with namespacing if both views have similar properties.

class AuthorsViewModel1 {
    public appName = "Two views demo";
    public currentView = ko.observable("authors");
    public authors = ko.observableArray<string>();
    public books = ko.observableArray<string>();
    public sortAuthorsAscending = ko.observable(true);
    public sortBooksAscending = ko.observable(true);
    constructor() {
        this.sortAuthorsAscending.subscribe(() => this.authors.reverse());
        this.sortBooksAscending.subscribe(() => this.books.reverse());
    }
}

In this case we need to keep track of the sort order for both lists. Since they are both in the same view model we are required to give them unique names. We could make this easier by using child view models. Let's make a view model for authors and one for books.

class AuthorsViewModel {
    public authors = ko.observableArray<string>();
    public sortAscending = ko.observable(true);
    constructor() {
        this.sortAscending.subscribe(() => this.authors.reverse());
    }
}
class BooksViewModel {
    public books = ko.observableArray<string>();
    public sortAscending = ko.observable(true);
    constructor() {
        this.sortAscending.subscribe(() => this.books.reverse());
    }
}
class FavoritesViewModel {
    public appName = "Two Views Demo";
    public currentView = ko.observable("Authors");
    public authorsVM = new AuthorsViewModel();
    public booksVM = new BooksViewModel();
}

What we did was move the properties that were specific to each view into their own view model. Then we reference those view models inside of our main view model, FavoritesViewModel. This makes it a lot easier to determine what data goes with which view.

Now we need a way to use those view models in our HTML file. Knockout has a control flow binding that can help us out with that. It's the "with" binding. The "with" binding specifies a view model to use for a specific section of HTML.

<body>
    <h1 data-bind="text: appName"></h1>
    <select data-bind="value: currentView">
        <option>Authors</option>
        <option>Books</option>
    </select>
    <div data-bind="visible: currentView() === 'Authors', with: authorsVM">
        <h2>Favorite Authors</h2>
        <label><input type="checkbox" data-bind="checked: sortAscending" /> Ascending</label>
        <ul data-bind="foreach: authors">
            <li data-bind="text: $data"></li>
        </ul>
    </div>
    <div data-bind="visible: currentView() === 'Books', with: booksVM">
        <h2>Favorite Books</h2>
        <label><input type="checkbox" data-bind="checked: sortAscending" /> Ascending</label>
        <ul data-bind="foreach: books">
            <li data-bind="text: $data"></li>
        </ul>
    </div>
</body>

If you look at the <div> for our favorite authors section it has a "with: authorsVM" binding. From that point down in the DOM the context for the data will be the AuthorsViewModel object. So now if you're in the authorsVM context and you click the sort order checkbox it's going to refer to the sortAscending property on the authorsVM model. Same for the favorite books section, it has a "with: booksVM" binding.

The "with" binding in Knockout makes it easy for us to separate our view models by view which make it easier to read and maintain our code when dealing with multiple views. We start with a primary application view model and add child view models to it then associate them with different views.

TypeScript What/Why/Who/Where/When

Using TypeScript instead of JavaScript can really help to develop and maintain medium to large applications. In this post I'd like to go over some of the situations where I think TypeScript would be beneficial by answering the What/Why/Who/Where/When of TypeScript.

What

Let's start with "what" since you need to know what TypeScript is before we can start. TypeScript is a typed superset of JavaScript that compiles down to plain old JavaScript. What this means is that TypeScript is JavaScript with a few features added, such as static typing. This means that you can specify what type a variable or parameter to a function is. TypeScript has a number of built in types: string, number, boolean, array, enum, any, void. In addition you can create your own types using interfaces, classes and enums.The benefits of static typing are numerous and will be discussed in the "Why" section below.

In addition, TypeScript also has support for many of the new features in the ECMAScript 6 specification such as modules, classes and arrow functions (modules are like namespaces or packages). These will get compiled down JS that is compatible with lesser versions of JS so you can use them in older browsers.

Why

This is the most important question. Why use TypeScript at all. JavaScript is just fine, right?

Well, the problem with JS is that it's very loosely typed (you could argue that's also one of it's strengths). For example, you can create a variable and set it to a string, then in the next line of code set it to a number, then set it to an object. Variables don't have types in JS.

Same with function parameters. In all actuality function parameters are just a convenience in JS. You can pass as many or as few parameters as you like to a function and JS won't care (the inside of the function may care, but not JS).

Same with objects. A JS object is just an associative array, or hash table, or dictionary, or whatever you want to call it. JS objects have no definite shape.

While the absence of typing can sometimes be a very powerful tool, it can also cause a lot of confusion. When writing large applications, using types gives you piece of mind. Once you get to the point where you can't keep the entire application in your head, typing provides protection and knowledge.

First of all it's like having a set of built in unit tests that get run every time you compile. We can all agree that it's better to find problems earlier rather than later at runtime. Would you rather have the compiler tell you exactly where the problem is, or step through your code in the debugger?

Secondly, all you have to do is look at a function's parameters and their types to know exactly what the function expects. Without it you have to look at the function body to know what the function is expecting, or write very good comments. There's no need to write comments if you can look at a variable or parameter and see what its type is. Its self documenting.

Lastly, TypeScript lets your IDE give you better tooling support. It's very hard for an IDE to give you auto complete and auto suggest information when using an untyped language such as JS. For example, it has no idea what types the parameters to a function are, therefore it can't tell you for certain what it expects. Same with objects; it has no way of knowing what fields an object contains. But once your IDE knows about the types of variables and parameters it can give you all kinds of help. It's another form of documentation. You also get better refactoring and usage finding support.

TypeScript also has what are known as type definition files. They provide type information about external JS libraries. That means you get all the tooling support you would expect for your favorite JS libraries including jQuery, Angular, Lodash, etc. (there a TD files available for nearly every popular library out there). No more going to look up documentation because you forgot the signature of a function call in one of these libraries, it's right there at your fingertips, including the types that the function parameters expect.

Who

Now that we know what TypeScript is and why you should use it, let's answer the question of who TypeScript is for. Anyone can use TypeScript of course. But if you are a Java or C# programmer you will feel right at home with TypeScript. That's because TypeScript bridges the gap between what classical OOP programmers expect and how JS does prototypal inheritance. Behind the scenes TypeScript does all the work of converting classes and modules into JS objects.

I think one of the biggest problems that programmers coming over to JS from languages like Java or C# have is that they just don't understand JS objects and how prototypal inheritance works. When I first started writing JS that was my biggest hurdle. I spent a lot of time and energy trying to make JS objects follow the classical OOP paradigms I was used to. With TypeScript you don't have to worry about that because it supports classical OOP.

Even if you are a JavaScript programmer you might want to consider using TypeScript for larger sized projects just to get better tooling in your IDE. It's also going to make it easier in a team environment for other team members to read and understand your code. Remember, TS is JS so you don't have to use every feature in TypeScript all the time. Just use the pieces you want and ease into it. I recently worked on a project with a JavaScript programmer and convinced him to use TypeScript just to get better documentation from type definitions. By the end of the project he also became a fan of static typing and plans to use TypeScript from now on.

Where

You can use TypeScript anywhere that you use JS. That includes single page applications (SPAs) in the browser or Node.js applications. Since TypeScript compiles to plain JS it can be used in any browser that supports JS. You can even start using the ES6 features that TypeScript supports now rather than waiting until all of the browsers get enough support that you can specifically target ES6.

When

Should one use TypeScript all the time? I don't think so. Yes, you heard me right. I like writing TypeScript but there are cases when it's overkill, I'll be the first to admit that. My recommendation, and the rule of thumb I use, is when I can't keep everything in my head anymore then I switch to TypeScript. For me that's when the code starts to take up more than a page of code or I start breaking my code into multiple files. If I can't see it all then I have to spend time moving around looking for things which slows me down. It's also going to make it harder for someone else to read your code.

Remember the golden rule of programming: Code is written for people to read, not computers.