ES7 Decorators

I read a fantastic article the other day by Addy Osmani, who among other things created Yeoman, TodoMVC, Material Design Lite, and who works at Google on Chrome and Polymer. The article was what we can expect from ES7 Decorators, which can be found below:

Exploring ES7 Decorators by Addy Osmani

You should definitely read the article because it is a succinct and clear explanation of decorators and what you would use them for. They are available to use now in both Babel, though not at the time of writing in Traceur. Generators along with other languages features like async/await, are major additions to JavaScript that should be coming along next year, so you should read up on them now! This article is just a quick summary of Addy’s with some different examples of what you can use decorators for.

You can check out the examples presented in this article in the online Babel REPL, as long as you check the “Experimental” checkbox. You can then run the generated result in something like JSFiddle.

So, what’s a decorator?

A decorator, put simply, is a function that can transparently wrap another function, class or property to provide extra functionality. Here’s what one might look like, from Addy’s article, a readonly decorator that prevents a class property from being overridden.

// decorators.js
function readonly(target, key, descriptor) {
  descriptor.writable = false;
  return descriptor;
}

export default { readonly }

// person.js
import { readonly } from 'decorators';

class Martin {
  @readonly
  dateOfBirth = '1990-09-25';
}

The @readonly declaration above the dateOfBirth property is how you would use the decorator, which in this case I’ve defined in another file. Let’s have a look at what happens if we try and write to the property:

let me = new Martin();
me.dateOfBirth = new Date();

// Exception: Attempted to assign to readonly property

You can see that you get target, key and descriptor method parameters in your decorator function. They each target different things and have their own properties:

  • target – The class that the decorator is used on.
  • key – If using the decorator on a property, this is the name of the property.
  • descriptor – Contains the properties value, enumerable, configurable, and writable for the property/function.

You can also define your decorator as a factory, so you can pass extra parameters into the decorator function. This can be used to do things like attach extra properties to a class. For example:

function gang(name, location) {
  return function(target) {
    target.name = name;
    target.location = location;
  }
}

@gang('The Warriors', 'Coney Island');
class Group() {}

@gang('The Riffs', 'Gramercy Park');
class Group() {}

@gang('Turnbull ACs', 'Gunhill');
class Group() {}

Thoughts

I don’t know about you but I’m getting really excited about using generators. They remind me of Attributes in C#, which I’ve used a lot before when writing REST APIs in .NET. I think they have massive potential in large frontend applications to tightly implement security functionality. For example, if you don’t want someone making certain API calls via the frontend (you should also apply the same rules on the API) you could do something like this:

function adminOnly(user) {
  return function(target) {
    if (!user.isAdmin) {
      toast.error('You do not have sufficient privileges for this area!');
      return false;
    }
  }
}

@adminOnly(app.identity.currentUser)
function deleteAllUsers() {
  app.api.users.delete().then((response) => {
    toast.success('Yay you deleted everyone!');
  });
}

Granted this is an extremely basic example that skips around things like Dependency Injection (if you’re using Angular) or ES6 import statements. I’ll be writing an article where I explore how decorators can be used with Angular in the future. What’s more important is the recognition of the power that decorators bring to JavaScript, and that they are something you should be keeping an eye on as ES7 is developed further and comes closer to release.

If you thought ES6 was good, ES7 is really exciting! Check it out!

Duration Parsing Using Juration

I’ve been working a lot with appointments and calendaring lately, and one of the requirements to create a new appointment was to have a duration parsing input that was easy to use. One that would let the user input combinations like 1h 10m or 3h or 25mins. It didn’t take me long to find Juration.

It’s a simple little library, only 2.6kb minified that does one thing and does it well, and it was exactly what I needed. For the string inputs, juration will return the equivalent number of seconds, which you can then determine the hours, minutes and seconds from. For example:

juration.parse('1h 30m');
// 5400

Juration also works the other way, you can give it a number of seconds and a formatting option and it will output the string representation, for example:

juration.stringify(5400, { format: 'long' });
// 1 hour 30 minutes

Juration parses anything from seconds up to years and is a simple, elegant solution for parsing duration inputs.

Angular Directive Isolate Scope Explained

I’ve written a lot of directives this year, and one of the best ways to learn the ins and outs of Angular is to write a lot of isolated directives with lots of different options. One thing I’ve still felt myself occasionally struggling with is the isolate scope on the directive definition object. Not the concept of the isolate scope, but just what in the hell the difference between all the little symbols you can use is. I aim to explain the difference between these symbols because there are some important things to know about them.

(more…)

A Review

Over the next week or so I’m going to be blowing out the cobwebs of this blog so to speak, in a review, because I’ve been neglecting it quite a bit and I want it to be a better platform for my tech writing. I’m aiming to:

  • Rewrite the theme (again) for an easier to read and navigate blog, including the return of syntax highlighting. I’d previously converted about half of my code samples to use gists but I am going to go back to using a syntax highlighter (probably prism or highlight.js) to reduce load.
  • Go through old posts and put disclaimers on those that are old and probably no longer valid, or have misleading information. I may just implement a flag for posts to display this warning so  I don’t have to do it manually.
  • Speed up the performance of my site. If anyone has any tips on speeding up WordPress I’m all ears, I’ve tried to do a lot of things but they don’t seem to work for long. I may end up upgrading to a larger digitalocean droplet.

Apart from that, I aim to come up with more articles more frequently, a lot about JavaScript since that is what I’m primarily working with now. Thanks for reading, the changes will be coming soon.

‘this’ is not allowed before super

I recently decided to try Babel out as a build system for work in place of Traceur. Along the way I found a spec-compliance issue in much of our ES6 Angular codebase. We have several main classes that other classes inherit common functionality from, for example a Model, Collection and Table class. These classes use dependency injection, naturally, because they are being used to write an Angular application.

To initialize the parent class and inject dependencies we were using the $injector.invoke() call on the child class like so:

// parent
class Collection {
  constructor($thingToBeInjected, Model) {
    this.Model = Model;
  }
}

// child
import Collection from './Collection';

class PeopleFactory {
  constructor() {
    class People extends Collection {
      constructor($injector, Person) {
        $injector.invoke(super.constructor, this, {
          Model: Person
        });
      }
    }
    
    People.$inject = ['$injector', 'Person']
    
    return People;
  }
}

export default PeopleFactory;

This was not a problem for us on Traceur v0.0.79 but as soon as I tried to run code like this through Babel it crashed and burned. The error I was getting was either:

'this' is not allowed before super()

or

'super property' is not allowed before super()

Both mean similar things. Basically, the older version of Traceur that we were using was not as spec-compliant as it should have been whereas the brand new Babel version I was using was. I checked it out on the latest version of Traceur and the exact same error came up.

In the spec, if you are extending a class you must call the super() method before accessing either this or a property of super e.g. super.constructor. The reasoning behind this is that technically JavaScript doesn’t know what this is until you call the superclass. Yehuda Katz gives a really great explanation of it on another similar babel.js issue.

I found all of this out by filing an error in the Babel repo at ‘this’ is not allowed before super() for AngularJS $injector.invoke() calls #1582. I got a quick reply from sebmck telling me that I was using a very old Traceur if this actually worked, and that this is the expected behaviour of the spec, which led me in the right direction.

Turns out sebmck had actually caused this issue to be fixed in the Traceur compiler too, as seen in the issue https://github.com/google/traceur-compiler/issues/1797.

So…how can we fix this?

As I mentioned this was all over our entire application so I had to spend an arduous couple of days fixing it. The solution was simple, but the find and replace was the most time consuming. Thankfully I had Johnny Cash’s At Folsom Prison album to keep my company while I worked. Here is what I needed to do – instead of importing the superclasses I made them into Angular factories and injected them into the child class that way. Here is what the class definitions looked after extensive rework.

// parent
class CollectionFactory {
  constructor($thingToBeInjected) {
    class Collection {
      constructor(Model) {
        this.Model = Model;
      }
    }
    
    return Collection;
  }
}

CollectionFactory.$inject = ['$thingToBeInjected'];

// child
class PeopleFactory {
  constructor(Collection) {
    class People extends Collection {
      constructor(Person) {
        super(Person);
      }
    }
    
    People.$inject = ['Person'];
    
    return People;
  }
}

export default PeopleFactory;

Notice that I moved $thingToBeInjected into the factory definition constructor, and I’m just returning the Collection class from the factory without initializing it. This leaves the subclass free to inject and extend it without importing it.

After replacing all of the $injector.invoke() calls and creating factories for our common classes the build went off without any hitches in the newest versions of Traceur and Babel!

Using $q.all() to Resolve Multiple Promises

If you have a lot of promises in Angular that need to be run sequentially, you can go about it in one of two ways. There is the classic way of chaining callback functions together to achieve the desired result. Assume that all of the functions in the example below follow this format:

function promiseX() {
    let deferred = $q.defer();
    
    ajaxCall().then((response) => {
        deferred.resolve(response);
    }, (error) => {
        deferred.reject(error);
    });
    
    return deferred.promise;
}

Consider the way of callback chaining your promise results.

let values = [];
promiseAlpha().then((val1) => {
    values.push(val1);
    promiseBeta().then((val2) => {
        values.push(val2);
        promiseGamma().then((val3) => {
            values.push(val3);
            complete();
        });
    });
});

This, as you can see, is not very pretty at all, and will make it difficult to a) get the resolved value of each promise and use it and b) chain more than a few promises without pulling your hair right out of its sockets. Thankfully there is an alternative in the form of $q.all().

The $q.all() method takes either an object or an array of promises and waits for all of them to resolve() or one of them to reject() and then executes the provided callback function. The values returned from the resolve function are provided depending on the way you give the promises to all().

If you provide them as an array, then the values will be available as an array with the same corresponding order of the promises array. For example:

let promises = [promiseAlpha(), promiseBeta(), promiseGamma()];

$q.all(promises).then((values) => {
    console.log(values[0]); // value alpha
    console.log(values[1]); // value beta
    console.log(values[2]); // value gamma
    
    complete();
});

However if you provide an object literal to all(), the values are attached to an object with the same corresponding property names in the all() callback. I find this way a lot easier because in most (but not all) cases you will have a set number of promises to complete.

let promises = {
    alpha: promiseAlpha(),
    beta: promiseBeta(),
    gamma: promiseGamma()
}
$q.all(promises).then((values) => {
    console.log(values.alpha); // value alpha
    console.log(values.beta); // value beta
    console.log(values.gamma); // value gamma
    
    complete();
});

This article comes out of a situation where I had to match values against ids from lists returned from an API, where the list data was not preloaded. As you can see, $q.all() becomes a very useful and much shorter way of chaining promise resolve()s than callback chaining.

Mocks, Stubs, and Injections: Unit Testing in Angular.JS

Unit testing in Angular is one of the framework’s biggest draws, and the framework’s huge focus on dependency injection makes it an ideal candidate for unit tests. This is very powerful when writing tests because any dependencies that your units or modules have can be easily mocked or injected, whether they are Angular modules or your own defined controllers, factories and directives.

I found that although this sounds good on paper, it can be quite difficult to achieve in a project whose build workflow involves about 12–15 gulp tasks, ~30 bower dependencies, and all of the modules written in ES6. Finding a way to compile the source files using Traceur and then loading them alongside the bower dependencies was a challenging endeavour, and this article aims to cover what I have found to be an ideal setup for unit testing a dependency-heavy Angular application using ES6 modules. This article will be quite lengthy, so feel free to skip ahead at any point.

(more…)

React-ions

I’ve been working with Angular a lot lately and I’ve been wrapped up in learning everything that comes with it, and it’s got me thinking whether full-fledged JavaScript frameworks are all they’re cracked up to be. Don’t get me wrong, I enjoy working with Angular and a lot of how it works and its design makes sense once you ignore the official tutorials and learn the best practices. But it feels like it has a lot of heft behind it, and sometimes the flow of data and UI interaction can get quite confusing once you have a large application.

I’d been seeing lots of mentions of React lately and it intrigued me enough to take a look. What I found were a lot of the things I’ve been thinking are not as simple as they could be in Angular, and a new way of thinking about UI interactions. And I really liked what I found. Now, I know that React is a library, the V in MVC while Angular is a full-fledged framework for building MVVM, MVC and MVW web applications. Library != Framework. So while I won’t be making many direct comparisons between the two, I may mention in this article some differences and similarities between them. Overall though, this is an article about what I like about React, and why I think you should take a look at it and try out some examples, even if you don’t intend to make a production application with it.

(more…)

ES6 Basics

I know I might be a little behind on this post, but I’ve been working exclusively on the front end at my new job and as a result I’ve been much more involved with JavaScript. We are using Angular.js and as part of our strategy of future-proofing (as much as you can for the front end) our application, we are using patterns likely to be used in Angular 2.0, which will use ES6 and Javascript Next functionality extensively. I’ve had to learn a lot of ES6 basics to effectively work with it and Angular together, and this article will go over what I think are the ES6 basics everyone should know.

(more…)

Learning Angular Q&A

While I’ve been learning Angular for the past couple of weeks, I’ve been able to get a pretty good idea of how the framework works as well as a lot of the best practices for it. While reflecting on what I had learned, I came up with several questions for myself to research to get a better understanding of more patterns and what I should use for certain things in Angular. Here are the questions I came up with and the results of my research.

(more…)