Features of ES6 Part 9: Classes

Tuesday, October 14, 2014 by K. Scott Allen
8 comments

Historically, many developers learn JavaScript after learning languages like C++, Java, C#, Ruby, or Python. All of these languages have a class keyword, and in many of these languages, the class keyword is the primary building block for constructing software.

In modern times, many developers learn JavaScript as a first language, so the new class keyword in ES6 will be a brand new tool.

Regardless of a developer’s background, the class keyword in JavaScript will play a role similar to the class keyword in other languages. Classes allow developers to define a blueprint for constructing objects. Each object a program creates from the class blueprint will be an object with the same methods and placeholders for data specific to each object.

We’ve always had the capability of building object with data and behavior in JavaScript, but like other ES6 features, the class keyword makes the common practice both succinct and more explicit.

The Keyword

Every class has a name, and a body containing the method definitions for the class.

class Employee {

    hire() {
        this.hired = true;
    }

    getStatus() {
        if(this.hired) {
            return "hired";
        }
    }
}

The above class has two methods: hire and getStatus. Notice we do not need to use the function keyword to define the methods. These methods will be available on every object we create using Employee, and as you can see in the implementation, these methods can save and retrieve state inside the object using the this keyword.

We create Employee objects using the new keyword.

let developer = new Employee();
developer.hire();

expect(developer.hired).toBe(true);
expect(developer.getStatus()).toBe("hired");

Quite often you’ll want an object to initialize itself with specific data right from the start. We can add this initialization logic using a constructor.

Class Constructor and Properties

Every class may specify a constructor. The runtime will invoke the constructor when instantiating a class, and we can use the constructor to initialize state in an object, often by accepting parameters in the constructor method.

class Employee {

    constructor(name) {
        this.name = name;
    }

    getName() {
        return this.name.toUpperCase();
    }
}

let developer = new Employee("Scott");
expect(developer.name).toBe("Scott");
expect(developer.getName()).toBe("SCOTT");

A class can also define a property with get and set to encapsulate a field.

class Employee {

    constructor(name) {
        this._name = name;
    }

    doWork() {
        return `${this._name} is working`;
    }

    get name() {
        return this._name.toUpperCase();
    }

    set name(newName){
        if(newName){ 
            this._name = newName;
        }
    }
}

let developer = new Employee("Scott");
expect(developer.name).toBe("SCOTT");

developer.name = "Alex";
expect(developer.doWork()).toBe("Alex is working");

ES6 also supports class inheritance and  interaction between a class and the class superclass. We’ll take a look at these features in the next installment of the series.

Confirm Password Validation in AngularJS

Monday, October 13, 2014 by K. Scott Allen
3 comments

AngularJSForm validation and custom validation directives are relatively easy with the changes in Angular 1.3. Try the sample plunk here.

Let’s look at the scenario where we need to confirm a new user’s password during registration. Registration is not so common in this day and age of federated identity, but is still a useful example and a frequent requirement.

Custom compareTo directive in AngularJS

A Custom Directive

We could put logic into a model to confirm a password, but it is probably better to separate the logic into a reusable directive. AngularJS already provides directives for the standard HTML validation attributes like required. All we need to do is follow a similar pattern.

1. Require the ngModel controller.

2. Add a method to the ngModel controller’s $validators object. Angular will invoke the function when the model value changes. The function returns a boolean, and a return value of false will set the corresponding ngModel’s $error property automatically.

The compare-to directive looks like the following:

var compareTo = function() {
    return {
        require: "ngModel",
        scope: {
            otherModelValue: "=compareTo"
        },
        link: function(scope, element, attributes, ngModel) {
            
            ngModel.$validators.compareTo = function(modelValue) {
                return modelValue == scope.otherModelValue;
            };

            scope.$watch("otherModelValue", function() {
                ngModel.$validate();
            });
        }
    };
};

module.directive("compareTo", compareTo);

You can use the directive inside of markup like so:

<input type="password" name="confirmPassword"  
        ng-model="registration.user.confirmPassword" 
        required 
        compare-to="registration.user.password" />
            
<div ng-messages="registrationForm.confirmPassword.$error" 
      ng-messages-include="messages.html"></div>

The ng-messages directives, also new in 1.3, makes it easy to provide common error messages for form inputs. You can also see them at work in the plunk.

Features of ES6 Part 8: Tagged Templates

Tuesday, September 30, 2014 by K. Scott Allen
2 comments

In a previous post we looked at template literals.

You might have glanced at the code in that post and thought: “gee, that’s useful”. Or, perhaps you are more the skeptical, security conscious type who thought “gee, new and easy ways to create injection vulnerabilities”.

Regardless of your initial take, an even more powerful feature in ES6 is the tagged template literal.

The tag is a function with the ability to interpret and process a template. The tag appears in front of the template, so in the following code the tag is upper.

var result = upper `${x} + ${y} is ${x+y}`;

The runtime will invoke the tag function and pass as a first argument an array containing the individual pieces of literal text from the template.

let test = function(literals, ...values) {
    expect(literals.length).toBe(2);
    expect(literals[0]).toBe("Hello, ");
    expect(literals[1]).toBe("!");
    return "test";
};

let name = "Scott";
let result = test `Hello, ${name}!`;
expect(result).toBe("test");

The template in the above code, `Hello, ${name}!`, generates an array of two values. The values contain only the literal text and no placeholders. The runtime will pass the evaluated expressions from any placeholders as individual arguments after the first array argument. It will be a common practice to capture the values using a rest parameter. Here is another code snippet showing all of the literals and values passed to the tag function.

let test = function(literals, ...values) {
    expect(literals.length).toBe(3);
    expect(literals[0]).toBe("Hello, ");
    expect(literals[1]).toBe(", ");
    expect(literals[2]).toBe("!");
    
    expect(values.length).toBe(2);
    expect(values[0]).toBe("Allen");
    expect(values[1]).toBe("Scott");
    
    return "test";
};

let firstName = "Scott";
let lastName = "Allen";
let result = test `Hello, ${lastName}, ${firstName}!`;

expect(result).toBe("test");

The general idea is that a tag function can build the result of a tagged template by concatenating strings. For each literal value, append the literal to the result and then append a value. However, a tag can interpret a template using any logic it desires, so if the tag simply wants to heedlessly return the string “test” regardless of the contents of the template, it can (as the code above is doing).

A more reasonable implementation of a tag might look like the following.

let upper = function(strings, ...values){
    let result = "";

    for(let i = 0; i < strings.length; i++){
        result += strings[i];
        if(i < values.length){
            result += values[i];
        }
    }

    return result.toUpperCase();
};

var x = 1;
var y = 3;
var result = upper `${x} + ${y} is ${x+y}`;

expect(result).toBe("1 + 3 IS 4");

The tag upper builds a result that would look just like the normal evaluation of the template literal, but uses toUpperCase before returning the result to ensure the result uses all uppercase letters.

The Significance of Tagged Template Literals

A tag’s ability to modify the output of a template is powerful. Imagine a tag that can build safe URLs by URL encoding a result, or a safehtml tag to build encoded HTML. Since JavaScript is often used to generate content (HTML, JSON, URLs, form encoded inputs, etc), a tag library that makes content generation safe and easy will be invaluable.

Even more interesting is the idea that the content inside of a template could be a language unto itself. The tag function could be the gateway to the interpreter for a domain specific language, which opens up many possibilities for the use (and abuse) of tagged template literals.

Want more? Watch JavaScript Fundamentals for ES6 on Pluralsight!

Features Of ES6 Part 7: Template Literals

Thursday, September 18, 2014 by K. Scott Allen
2 comments

Template literals provide JavaScript with some basic string formatting capabilities. Just like many template technologies, template literals in JavaScript consist of literal text, and placeholders where the runtime can evaluate an expression to poke data into the text.

let name = "Scott";
let message = `Hello, ${name}!`;

expect(message).toBe("Hello, Scott!");

Backtick characters (`) enclose the entire template literal, while $ and {} denote the substitutions. Inside a substitution, you can use identifiers and expressions.

let showTheMath = function(x,y ){
    return `${x} + ${y} is ${x + y}`;
};

let result = showTheMath(3,4);

expect(result).toBe("3 + 4 is 7");

Template literals can even span multiple lines.

let message = `This is
               a short, but multi-line message`;

Note that message will contain a newline character because newlines (and trailing spaces) are significant inside of a template literal.

Template literals are a useful addition to the language. However, template literals become exceptionally interesting when using them with a tag. We’ll look at tagged template literals next week.

Want more? Watch JavaScript Fundamentals for ES6 on Pluralsight!

Declarative Physics with PhysicsJS and AngularJS

Wednesday, September 17, 2014 by K. Scott Allen
3 comments

PhysicsJS + AngularJS One of the reasons for Angular’s success is the flexibility in the building blocks the framework provides. There is a delicate balance between productivity and flexibility. A heavily opinionated framework can be make a team highly productive, but the opinions can also make it harder to mix in additional features that conflict with the opinions, or sit outside the vision for the framework. Angular strikes a nice balance.

When I first thought about mixing PhysicsJS into an AngularJS application, I couldn’t see how a library based on timer ticks, frame rates, and a canvas could work with a framework like Angular, with its digest cycle and directives.

But, after 30 minutes I discovered that not only could these two work together, but Angular was flexible enough to provide some nice enhancements to the PhysicsJS experience.

Go to PhysicsJS + AngularJS to see the following code in action. The code is based on the tutorial “Creating a scene of colliding polygons”. 

Services

The first order of business is wrapping PhysicsJS components with services. Physics is the primary export of PhysicsJS, and this object provides factory methods to create shapes and behaviors. We can inject Physics into other components of the application that need to create shapes, but we’ll also create some additional services that use Physics to setup the “game loop” ticker and the world that contains all the shapes and behaviors for a scene.

var app = angular.module("app", []);

app.value("Physics", Physics);

app.factory("world", function (Physics) {
    var world = Physics();
    world.on("step", function () {
        world.render();
    });
    return world;
});

app.factory("ticker", function (Physics, world) {
    var start = function () {
        Physics.util.ticker.on(function (time) {
            world.step(time);
        });
        Physics.util.ticker.start()
    };

    return {
        start: start
    };
});

Directives

Directives can transform a PhysicsJS scene from imperative code and into a declarative language.  Here are a few simple directive definitions.

app.directive("physicsBehavior", function (Physics, world) {
    return {
        restrict: "E",
        scope: {
            name: "@"
        },
        link: function (scope) {
            world.add(Physics.behavior(scope.name));
        }
    };
});

app.directive("physicsBody", function (Physics, world) {
    return {
        restrict: "E",
        scope: {
            options: "=",
            body: "=",
            type: "@"
        },
        link: function (scope) {
            scope.body = Physics.body(scope.type, scope.options);
            world.add(scope.body);
        }
    };
});

These types of directives will let us write markup like the following.

<physics-canvas width="500" height="500">

    <physics-body type="rectangle" body="main.box1"
                  options="{x:450, y:10, vy:-0.3, width:5, height:5}">
    </physics-body>

    <physics-body type="rectangle" body="main.box2"
                  options="{x:250, y:210, vy:-0.3, width:5, height:5}">
    </physics-body>

    <physics-edge-detection min-x="0" min-y="0" max-x="500" 
                            max-y="500" restitution="0.3">
    </physics-edge-detection>

    <physics-behavior name="constant-acceleration"></physics-behavior>
    <physics-behavior name="body-impulse-response"></physics-behavior>
    <physics-behavior name="body-collision-detection"></physics-behavior>
    <physics-behavior name="sweep-prune"></physics-behavior>

</physics-canvas>

Controllers

Controllers can build models that interact with objects in the PhysicsJS world. The API allows us to apply forces and change the geometry of objects. One difficulty I did have is seeing the updated appearance of a shape after changing attributes. The code needs to set the view property of a shape to null for changes to attributes like width and height to appear. PhysicsJS will recreate the view on the next tick. 

model.kick = function () {
    model.box1.applyForce({x: 0.1, y: -0.2});
    model.box2.applyForce({x: -0.1, y: -0.2});
};

model.grow = function () {
    model.box1.geometry.width *= 1.5;
    model.box1.geometry.height *= 1.5;
    model.box1.mass *= 1.5;
    model.box1.view = null;
    model.box1.recalc();
};

But What About The Digest?

Anyone who has worked with jQuery widgets or native events knows that Angular needs to know when model data changes in order to update the DOM with new model values. Generally we accomplish this goal by wrapping code inside a scope’s $apply method.

The interesting thing about working with PhysicsJS is that the physics engine is constantly updating a canvas based on a timer, so it is not necessary for Angular to know about changes in shape properties, like position and acceleration. It just works.

Summary

Although there would be a lot more work needed to make a complete and general purpose wrapper for PhysicsJS, the integration with an Angular app works in a straightforward manner. 

C# 6.0 Features Part 3: Declaration Expressions

Monday, September 15, 2014 by K. Scott Allen
10 comments

In C# we’ve always had declaration statements for declaring variables, and expression statements to produce values.

In C# 6 we can mix a declarations with an expression to declare a new variable and produce a value.

The canonical example is the int.TryParse method, which requires an out parameter. In previous versions of C# the parameter would be declared in a distinct statement before the invocation of TryParse.

int result;
if(int.TryParse(input, out result))
{
    return result;
}
return 0; // note: result still in scope

With C# 6.0, the same result is achievable with a declaration expression. The declaration statement also limits the scope of the variable passed as an out parameter.

if (int.TryParse(input, out var result))
{
    return result;
}
return 0; // result is out of scope

We could also transform the above code into a one-liner. . .

return int.TryParse(input, out var result) ? result : 0;

. . . and then package it into an extension method for string.

public static int ParseIntSafe(this string input, int @default = 0)
{
    return int.TryParse(input, out var result) ? result : @default;
}

With declaration expressions we can also declare variables inside if statements . . .

if ((var address = user.HomeAddress) != null)
{
    // work with address ...

    return address.City;
}

. . . and the various looping statements.

int result = 0;
foreach (var n in var odd = numbers.Where(n => n % 2 == 1).ToList())
{ 
    result += n + odd.Count();
}
return result;

Declaration are a small addition to the C# language, but will come in useful in a few scenarios.

Features Of ES6 Part 6: Destructuring

Thursday, September 11, 2014 by K. Scott Allen
3 comments

To destructure an object is to dismantle or tear apart an object.

In ES6, a destructuring assignment allows us to tear apart an array or object into individual pieces that we can assign to variables. The square brackets [ and ] are used to destructure an array, while { and } will destructure an object.

The following code will destructure an array so that x contains 22 and y contains 44.

let values = [22, 44];
let [x, y] = values;

expect(x).toBe(22);
expect(y).toBe(44);

You can think of [ and ] in the first line of code as the symbols used to construct an array. The [ and ] on the second line of code tear apart the array and declare two variables to hold the pieces.

Destructuring objects follows the same pattern, but will use { and }.

var person = { firstName: "Scott", lastName: "Allen" };
var {firstName, lastName} = person;

expect(firstName).toBe("Scott");
expect(lastName).toBe("Allen");

You do not need to use let or var with destructuring to create new variables, you can also destructure into existing variables.

let x = 10, y = 20;

// swap!!
[x,y] = [y,x];

expect(x).toBe(20);
expect(y).toBe(10);

You can also destructure arrays and objects returned from a function call.

var doWork = function() {
    return [1, 3, 2];
};

let [, x, y, z] = doWork();

expect(x).toBe(3);
expect(y).toBe(2);
expect(z).toBeUndefined();

Note a couple special properties in the destructuring of doWork’s result. First, the opening comma will skip the first array element, and you can use additional commas anywhere to skip additional elements. Secondly, if there are not enough array elements to satisfy all the variables required by the destructuring, the extra variables will receive the value undefined.

You can also destructure in a function parameter list.

let doWork = function({firstName, lastName, role="developer"}) {
    return role + " " + firstName + " " + lastName;
};

let person = {firstName: "Scott", lastName: "Allen"};
let result = doWork(person);

expect(result).toBe("developer Scott Allen");

The above example also uses a default parameter value to assign “developer” to the role parameter in case the incoming object does not have a role property (otherwise, role would receive the value undefined). Default parameters are not restricted to function declarations when using destructuring.

let address = { state:"Maryland" };
let { state="New York", country="USA"} = address;

expect(state).toBe("Maryland");
expect(country).toBe("USA");

Rest parameters can also capture the remaining elements of an array.

let odds = [1,3,5,7,9];
let [first, second, ...rest] = odds;

expect(first).toBe(1);
expect(second).toBe(3);
expect(rest).toEqual([5,7,9]);

Destructuring can also drill into complex objects, even objects with collections inside.

let employee = {
    firstName: "Scott",
    address: {
        state: "Maryland",
        country: "USA"
    },
    favoriteNumbers: [45,55,32,13]
};

let { firstName, address: {state}, favoriteNumbers: [,second]} = employee;

expect(firstName).toBe("Scott");
expect(state).toBe("Maryland");
expect(second).toBe(55);
The Significance of Destructuring

One area where destructuring will lead to more maintainable code is in the use of configuration objects, like the configuration objects you typically pass to HTTP communication methods like jQuery’s ajax method. Finding the available options and their defaults is often difficult when using such a method, and maintaining the options and defaults can be tricky as an author. With destructuring, configuration options and defaults become more explicit.

let httpPost = function(
        url, {
        cache = true,
        contentType = "application/json",
        timeout = 2500,
        headers = {},
        // ...
    }) {
        // ...
};

We’ll also see other uses for destructuring as we move through additional features of ES6, like modules.

Want more? Watch JavaScript Fundamentals for ES6 on Pluralsight!

by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!