TAD (Test After Development)

Testing is a crucial part of any modern development process. If you’re not testing your code, you might as well be writing it blindfolded and hoping when you push to production that it works, if the company doesn’t go bankrupt from all of the bugs first.

But, I am a realist. Being honest, we all start out wanting to build things right. We want to test everything, writing both unit and integration tests to make sure everything works as intended. The company you work for might even allow for time to write tests until reality hits you on the back of the head.

Priorities change. The higher-ups want the product you’re working on to ship in two months, and there is easily four months of work in Jira, it’s going to be a mission to get it all completed in time.

In my experience, tests are usually the first thing to be removed in the face of more pressing priorities (like actually building the product and making money).

A word on Test Driven Development (TDD)

I have always been a fan of test-driven development. And I have been fortunate to be in a position where I have been able to explore TDD, and when it works, boy does it work. By works, I mean when a company agrees to invest the time into a test-driven development process.

Every project I work on, my first thought is “TDD would be great for this”, but once again, priorities shift, and it becomes hard to justify the short-term investment for the long-term gain that TDD provides. Even if your entire development team wants something, management gets the final word, and it all comes down to money in the end (we’ll talk about that later).

You need tests

In an ideal world, we would all be writing our tests first and then making our code make them pass, make them fail, make them pass. A good test not only helps you design clean code, but it also has the added benefit of documenting your code as well.

If TDD is more time consuming and harder to justify to your company, does this mean you give up on writing tests completely? Heck no.

In any medium to large application, tests are as crucial as decent server infrastructure; they should be the oxygen to your app brain. No oxygen and the brain will slowly die.

Inevitably, many developers end up resorting to TAD (Test After Development) because it’s easier and faster (at least initially). Writing the code first and then going back and writing the tests after the fact. It is not super ideal, but any tests are better than no tests.

Many would argue that if you get into the habit of TDD, over time, you will get faster at writing tests and code, that the long-term benefits outweigh the short-term caveats. The buy-in from stakeholders is the hard part. If it were easy, everyone would be doing TDD.

The longer you work on a project, the more crucial tests become. As the scope widens and feature set increases, things are more likely to break, and some of your architectural decisions early on are bound to come back and bite you (something that TDD would help you most likely avoid).

The whole point of TDD is that initially, work takes longer to complete than not prescribing to TDD, but your code will be more stable and less error-prone.

An experienced surgeon doesn’t rush to cut you open and perform heart surgery right away; they take their time and slowly get the job done. Programming is not heart surgery, but if you’re working on critical systems where functioning clean code is essential (like a space shuttle or nuclear power plant), it’s equally as important you get it right.

However, it all comes down to cost

The deciding factor in any decision you make within your company always comes down to money. The short-term benefits of TDD are hard to quantify, and if you do your job correctly, the number of bugs and refactoring work you need to do will be substantially lower (almost zero), but how do you prove that to non-technical higher-ups?

You can’t. It’s all well and good to say we have fewer bugs since adhering to TDD principles, but it is challenging to prove that TDD is the reason for that and not just increased familiarity and skill-level being the main factor.

  • Does it take more time to finish a task? Yes.
  • Will it cost the company more time and money? Yes.
  • Will there be a learning curve for inexperienced developers (especially juniors)? Yes.

Once again, you could argue that writing the code and then writing the tests, going back and refactoring your code and then having to fix your tests takes a lot more time using TAD: you’re right. Looking at TDD through neutral coloured glasses, there are more benefits than downsides if time is not an option.

But, the industry is weird. Many managers still measure the value and productivity of developers by the number of lines of code they write and commits they’re pushing up. And what produces the most lines of code and commits? TAD. It’s inefficient, but even non-technical people can see you look busy.

Developer A and Developer B side-by-side, Developer A is writing and shipping code faster than the other. It might be laden with errors and horrendous compared to Developer B’s well-architected and clean code, but it works and if there is one thing managers love more than saving money, it’s shipping code on time.

Conclusion

If you can’t convince the company you work for to give TDD a chance, TAD is still an acceptable albeit less than the ideal alternative of no tests. As long as you have tests, there is always room for improvement.

What I Love About Aurelia

There is no shortage of Javascript frameworks and libraries to choose from. Notably, you have Angular, React, and Vue, which are the most discussed and used.

If you are a regular reader of my blog, you know how much I love Aurelia and have blogged about it since early 2015. If you are new, let me quickly introduce myself.

I have been a developer for 11 years now, working in the front-end space. My experience stems back to the likes of; ExtJS, YUI, Backbone, Knockout, Durandal and Angular v1. Believe it or not, I also used to work with React back in 2014/2015.

I still remember seeing the post on Hacker News announcing the Aurelia alpha release. The date was January 26th, 2015. After reading through the website and goals of the framework as well as being familiar with Rob’s previous work, I gave it a go and never looked back.

Since 2015, I have been working with Aurelia daily in my day job (current job as well as my previous job) as well as side-projects and random ideas; there isn’t a project that I haven’t used it on.

Aurelia promotes strong separation of concerns

When I first started in web development, the one thing ingrained into me from the beginning was: separation of logic and templating, or separation of styles and markup also known as Separation of Concerns (SoC).

Web pages by their natural order promote separation by concern. HTML is used to structure and define the page; CSS is used to style the HTML and Javascript responsible for page interaction and logic.

In Aurelia, your business logic gets handled within a view-model, markup handled inside of a view and styling is handled inside of a stylesheet. When you think about it, Aurelia doesn’t try replacing what browsers and specs already give you; it enhances them.

Separation of concerns is a repeated theme throughout the framework. Components, custom attributes and routed views all utilise the same conventions and approach to writing a web application.

Think about how you would develop a web application or page without a framework these days, and it would be an HTML file for the markup, a stylesheet for the styling and a Javascript file which contains any logic for interacting with the page or dealing with data. No conventions, just basic concepts that never change, this is what it is like building in Aurelia.

I do not want to turn this post into a framework/library bashing contest, but this is one of the things I dislike about React. It reminds me of working with PHP applications (not using a framework) where business logic, styling and markup are all intertwined with one another.

There might be other ways these days with later versions of React, but the basic premise is you stuff a bunch of XML like HTML (JSX) inside of a render function which is called by React. You break up you UI into smaller components and use props to pass data through to them. While JSX is not required, it is the most commonly used syntax I have seen for authoring React components.

Let me acknowledge that A) I haven’t worked with React in a few years and B) I am biased because of my use of Aurelia. Please correct me if any of my assumptions and claims about React are inaccurate, and I can amend them.

Batteries included, no glue required

One of my absolute favourite things about Aurelia is the fact it gives you almost everything you need out-of-the-box. It gives you powerful templating, API’s, dependency injection, routing.

Then you have the plethora of plugins on offer for other functionality. Want to use Fetch with more beautiful syntax and error handling? Aurelia Fetch Client. Want to localise your application into other languages? Aurelia i18n. Need a configurable modal in your application? Aurelia Dialog.

If you want to add in state management to your Aurelia application and don’t want to get a frontal lobotomy using something over-engineered and complicated like Redux, there is Aurelia Store which is an RxJS powered state management library compatible with the Redux Dev Tools browser extension.

In my experience working with other frameworks and libraries; some require glueing together a lot of independently maintained dependencies to build what is essentially a framework.

Why waste your time creating a framework piece-by-piece every single time you want to build something. Save yourself the node_modules weight and time, use something that gives you what you need straight away.

Aurelia can be used without needing a bundler or build process

If your experience goes as far jQuery where you drop in a script and start writing code, then the ability to use Aurelia in script form might appeal to you. Thanks to Aurelia Script, you can add in a script and starting authoring powerful web applications.

Not only is this approach useful for quick prototyping on Codepen or Codesandbox, it means you spend less time battling with complicated build process in Webpack and fixing complex issues and extension incompatibilities.

If I am honest, not many of us enjoying configuring Webpack, opting to pull out our teeth with a pair of pliers instead.

It has no Virtual DOM

Thanks to other popular frameworks and libraries, the words Virtual DOM have become synonymous with developers naively believing that it means fast applications. While the Virtual DOM is impressive from a technical perspective, it’s not the only way to achieve fast performing web applications.

In Aurelia, the binding system is reactive; this means that when something changes, it gets updated in your view. Because there is no Virtual DOM, you’re working with just the real DOM, and you can use third-party libraries which need to touch the DOM without any problems.

The more you read into what a Virtual DOM is and how it works, the more you realise it’s not necessarily always the most performant choice.

It’s easy for newcomers and all skill level developers

I have seen developers upskill in Aurelia from a multitude of levels. I have seen back-end developers grasp Aurelia in a few days, I’ve seen front-end developers used to working with jQuery or React also get it quickly, and I have seen newcomers grasp it equally as fast.

I think this is a unique selling point for Aurelia; you don’t need a PhD in Javascript to know what is going on with it. Its conventions based approach means you spend less time configuring Aurelia and more time writing code.

The Aurelia CLI is fantastic

All useful frameworks and libraries these days have a CLI which allow you to get a starting application up and running with the features and coding styles needed: Aurelia is no exception.

There isn’t anything unique about the Aurelia CLI, but it makes your life a lot easier when you’re building a new project.

Familiar syntax, aligned with standards

In an era where framework and library authors are reinventing the wheel or introducing foreign concepts not found in any specification, Aurelia goes against the grain by leveraging standards-based concepts and API’s.

The templating syntax for displaying a value uses the same interpolation syntax ${myVariable} that you would inside of template literals inside of your Javascript/TypeScript code. Binding to properties is equally as intuitive, want to bind a value on a form input? <input type="text" value.bind="bindToThis">

If you want to use Web Components with Aurelia, there is a plugin for that and the next version; Aurelia will be aligned with the HTML Modules specification to give you single-file components like you might find in Vue, only standards-based.

This is one of the most unique features and selling points of Aurelia. It allows developers to work in a way that is familiar, a way that requires very little buy-in with the intent to eventually allow official specifications to replace features found in Aurelia.

Working With An API In Aurelia Store

Unless you’re working on a completely static web application, chances are you’ll be needing to get data from an API or send data to one. In Aurelia, you would usually do this either using the HTTP Client or Fetch Client (you should be using Fetch). However, what about Aurelia Store? The versatile state management library for Aurelia.

You have two approaches you can take when using Aurelia Store with an API, and we’ll discuss the pros and cons of each one. This article is going to be a small and relatively non-technical article.

Make API requests from within your actions

Aurelia Store supports asynchronous actions, meaning you can delay their execution until the async function promise resolves. A simple Aurelia store action might look like this if using async.

async function myAction(state) {
    const newState = { ...state };

    // Do something in here

    return newState;
}

When you return from within an async function, it’s akin to a Promise.resolve the entire function itself becomes wrapped in a promise, but we’re not going to go into specifics of how async/await works in this post.

Making a function async means, you can call an API from within your action and then store the result in your state when it loads. This simplified code assumes that you’re accounting for errors in the loadUsers, hence there not being a try/catch block below.

async function myAction(state) {
    const newState = { ...state };

    newState.users = await api.loadUsers();

    return newState;
}

This approach works well because it means you can load data through actions, they are easier to debug, and you can perform transformations on the data returned. It also makes refactoring your code so much easier as you only need to change one action.

However, the downside is if the request above takes longer than expected. Maybe you’re using an Azure or Google Cloud Function (lambda function), and it takes a few seconds to start because it’s not warmed up, this request might take a few seconds to complete and meanwhile, your application slows down to a crawl. If you’re calling multiple actions, it’ll delay calling the other actions until the current one returns a state.

If you keep an eye on your actions and ensure the requests are tiny, then this should never be a problem. Adding a visual loading indicator into the application can also alleviate any loading issues. However, assumption-led decision making can sometimes backfire.

API Call First, Dispatch Action Second

In the above approach, the request and action are one function. In this approach, you request the data first and then dispatch an action after.

There is an obvious upside to this approach. Your actions execute fast; they don’t have to wait for API calls to resolve before continuing. Another upside is that it ensures your state layer and API logic remains separate. The maybe not-so-obvious downside is you now have to write and maintain two different pieces of code.

async function myAction(state, users) {
    const newState = { ...state };

    newState.users = users;

    return newState;
}

async function loadUsers() {
    const request = await fetch('/users/all');
    const response = await request.json();

    return response;
}

export class ViewModel {
    async activate() {
        const users = await loadUsers();
        dispatchify(myAction)(users);
    }
}

But, which one do I use?

The point of this post is not to tell you that you should use one over the other; it is to point out that the two approaches have upsides and downsides. Either all is fine, you only need to be aware of the caveat of async actions. When you create an asynchronous function, they all become async.

I use the second approach in my Aurelia applications. I like decoupling my state management from my API logic completely. It means if I want to remove state management at a later date or use something else, there is no tight coupling in my code. Remove my actions and call the API functions myself from my view-models (or wherever).

My Thoughts On GitHub Sponsors

It’s hard to believe that it has almost been a year since Microsoft completed its acquisition of GitHub. While a vocal number of people in the community decried the decision and some moved to GitLab since the acquisition Microsoft has made a series of positive moves.

It all started with GitHub making private repositories free in January 2019, up to three collaborators. This is a move that directly competed with competing Atlassian owned source control platform Bitbucket which offered free private repos as well.

And then recently, GitHub announced GitHub Package Registry, an in-preview up and coming rival to npmjs for Node packages, but also extending to other languages and tying in with the repository itself.

And then not too long after that, most recently, GitHub announced GitHub Sponsors allowing individual repository owners to be paid for their open source contributions.

While the latest new feature has been applauded by many, some see it as aggressive and an attempt by Microsoft to push similar open source sponsoring platforms out using its size and power to do so.

One such popular offering for open source is Open Collective, projects like Webpack and Aurelia use it so the community and companies can sponsor and fund development. With GitHub Sponsors, initially, the feature is only available for individuals, but presumably, once it goes public organisations will be able to opt-in to the feature as well.

Another popular option used by the likes of Vue.js (raking in six figures yearly in donations) is Patreon. These platforms, however, are disconnected from the projects themselves, requiring users to signup to a separate service to use.

I see GitHub Sponsors as a brilliant and much-needed move by Microsoft and GitHub. Funding and open source is a constant hot topic and while other services do exist, they are not integrated with GitHub itself. An in-built way of soliciting monetary contributions and all without requiring users to signup to another service, it’s a huge win for open source.

Best of all, GitHub is forgoing fees for the first year and then charging them after. But, it’s a nice incentive to join and try it out without losing anything. If it works, projects will presumably keep using GitHub Sponsors for their projects and if not, use a different offering.

Will GitHub Sponsors make people all of a sudden start paying for the free software and code they’re benefitting from? Who knows. All I know is this is a void that needed to be filled, one that GitLab and Bitbucket failed to address as well (and presumably will copy).

Masked Inputs In Aurelia: The Easy (and reliable) Way

When it comes to adding in masked inputs into a modern Javascript web application, it is easier said than done. The task at hand is simple, yet, under the surface is paved with complexity in a framework with unidirectional data flow.

The problem I am going to describe is also a problem you’ll encounter in Angular, Ember, Vue and any other framework or library which offers two-way binding on input elements or modifying the input itself.

The Problem

You have an input element. You want users to be able to enter a value and automatically format it as they type. This input could be anything, but in my situation, the input was for entering numeric values.

I wanted the value to automatically add a comma for the hundreds, add two decimals to the end and a dollar sign ($) symbol as a prefix to the value.

By default in Aurelia, binding on input elements is two-way. This means the value is both updated in the view and view-model, which in many cases is great.

As you can imagine, in the case of wanting to format an input element automatically you are instantly fighting with the framework. The problem is the plugin that does the formatting is modifying the input, and Aurelia itself is also modifying the input.

Why not a value converter?

You can create a value converter (my first attempt) and leverage the toView and fromView methods for mutating the values going to and from the view.

A value converter gets you quite a lot of the way, but one problem you will encounter is the caret position will jump to the end. When the value is modified in the input, the entire input is effectively refreshed and the cursor jumps to the end of the value which is jarring and annoying.

How about a custom attribute?

My second attempt involved using a custom attribute that listened to the input and blur events. I added in some checks of the value and attempting to work around the caret position by reading it whenever the input was modified and setting the position after.

Ultimately, I fell into some of the same problems the value converter presented to me. Getting and setting the caret position is tricky business and something I ideally do not want to maintain in the long-term, having to work around issues in different browsers is another problem there.

I knew the only solution had to be leveraging an existing input mask library. A library which supports a plethora of formatting options, masks, working with currencies and other types of data and most importantly: solves the caret jumping problem.

The Solution

I tried a lot of different approaches, referencing implementations for not only Aurelia but Angular and Vue as well. However, the common theme in many of these solutions is they were very complicated. One such plugin I found was over 600 lines of code, many of those specifically for getting and setting the caret.

The final solution ended up being laughably simple, in hindsight. I will show you the code and then run through it below. I am using the inputmask plugin which is a battle-tested and highly configurable input masking plugin.

Whatever library you choose to use, the code will end up looking the same if you follow the approach I have taken.

import { inject, customAttribute, DOM } from 'aurelia-framework';

import Inputmask from 'inputmask';

@customAttribute('input-mask')
@inject(DOM.Element)
export class InputMask {
  private element: HTMLInputElement;

  constructor(element: HTMLInputElement) {
    this.element = element;
  }

  attached() {
    const im = new Inputmask({
      greedy: false,
      alias: 'currency',
      radixPoint: '.',
      groupSeparator: ',',
      digits: 2,
      autoGroup: true,
      rightAlign: false,
      prefix: '$'
    });
    
    im.mask(this.element);
  }
}

export class CleanInputMaskValueConverter {
  fromView(val) {
    if (typeof val === 'string' && val.includes('$')) {
      // Strip out $, _ and , as well as whitespace
      // Then parse it as a floating number to account for decimals
      const parsedValue = parseFloat(val.replace('$', '').replace(/_/g, '').replace(/,/g, '').trim());

      // The number is valid return it
      if (!isNaN(parsedValue)) {
        return parsedValue;
      }
    }

    // Our parsed value was not a valid number, just return the passed in value
    return val;
  }
}

export class PrecisionValueConverter {
  toView(val, prefix = null) {
    const parsedValue = parseFloat(val);

    if (!isNaN(parsedValue)) {
      if (prefix) {
        return `${prefix}${parsedValue.toFixed(2)}`;
      } else {
        return parsedValue.toFixed(2);
      }
    }

    return val;
  }
}

The solution in its simplest terms is three parts:

  • A custom attribute applied to input elements called input-mask which instantiates the plugin and applies the masking options
  • A value converter which strips away any fragments of the mask; $, _ and ,, trims whitespace and then parses the value using parseFloat
  • A value converter which formats a value passed from a view-model and adds a prefix (if specified) and converts the value to a precision of 2 decimal places

During this exploration phase, I stumbled upon a powerful and awesome feature in Aurelia that I did not even know was possible, multiple value bindings. You will notice below that I have a value.one-time as well as a value.from-view binding on the input.

The reason for this was I wanted to initially set the value and then not worry about syncing it again. This allows data loaded from the server to be passed in (initial values, etc). The value.from-view binding updates our view-model every time the value changes.

<template>
    <input 
        type="text"
        value.one-time="value | precision" 
        value.from-view="value | cleanInputMask"
        input-mask>
</template>

It makes a lot of sense that you can do this, but it’s not a documented feature and initially, I wasn’t 100% confident it would work. I am an experimenter, so the worst-case scenario was it wouldn’t work. This is what I love about Aurelia, it can handle anything that you throw at it, even things you think might not work, but end up working.

Basically, this approach creates an inline binding behaviour where you control the direction of the updating process, which is quite powerful and cool.

A great addition to Aurelia itself could be a binding attribute which offers this functionality (allowing a once to view and always from view mode).

Conclusion & Demo

The end result can be seen here, as you can see we have a nicely formatted as you type input element. This was built for a specific use-case so it is missing configuration options, however, I have created a repository here which will have a plugin-friendly version of this soon.

Saved By The Aurelia Portal Attribute

Recently at my day job, I encountered a very specific scenario that I wrestled with for quite a bit. I had a routed set of views, which were using a layout view template because it needed a very specific markup for positioning using CSS Grid.

The issue I had was although the route layout had a <slot></slot> element inside of it for projecting the routes, I wanted a custom navigation element to be projected inside of the routed view. Previously there was a bit of duplication to add the custom element into the right area.

I initially tried to use router View Ports to achieve the result I needed, but they’re more designed for rendering sub-views within a view, I needed to render a component into a specific area of the page and have it react to route change events.

Then I remember the Portal attribute by core team member Binh Vo, it has actually been around for a while now. I haven’t had a need for this plugin, until now. In my situation, I needed to leverage the target property of the attribute to tell it where to inject my custom element and everything worked as expected.

My layout view simplified looks like this:

<section>
    <main-nav></main-nav>
    <inner-nav portal="target: #nav-slot;"></inner-nav>
    <slot></slot>
</section>

For each routed view the simplified markup looks like this:

<template>
  <main>
    <div class="dashboard-wrapper">
      <div class="inner-content">
        <section>
          <div id="nav-slot">
            <div class="content">
                <h1>Some content</h1>
            </div>
          <div>
        </section>
      </div>
    </div>
  </main>
</template>

When this routed view is loaded, the portal attribute will inject the element from the router layout into the DIV with the ID nav-slot. Super simple stuff and it does exactly what I needed it to do. The portal plugin can be found on GitHub here and it’s great to see how it all functions behind-the-scenes. A demo of the plugin in action can also be found here.

Creating Your Own Javascript Decorators in Aurelia

Decorators are currently a stage 2 proposal in Javascript and they allow you to decorate classes, class properties and methods. If you have worked with Aurelia for longer than 5 minutes or other frameworks such as Angular, you will already be familiar with them.

At the core of a decorator, it is a function that returns a function. It wraps the context of wherever it is applied. Decorators allow you to add new properties/methods to a class or change existing behaviours.

Aurelia already utilises decorators quite extensively, but it does not rely on them for everyday use. The existence of decorators allows you to mark your applications up using convenient shorthand.

It is important to remember that decorators are a Javascript language construct and not specific to any framework like Aurelia. Given Aurelia leverages ES2015 classes, we can create and use our decorators without changing anything.

Decorator Types

When we talk about decorators, there are three categories. A class decorator (decorates a class), a class field decorator (inline properties on classes) or a method decorator (a function, either standalone or within a class). You can even create a decorator that combines all three types into one. For the context of this article, we will only be focusing on class decorators.

Creating a class decorator

If you have used Aurelia a little bit, decorators such as; @inject, @singleton and @customElement might be familiar to you already. These are examples of a class decorator.

The inject decorator is used in the following manner:

import {inject} from 'aurelia-framework';
import {Router} from 'aurelia-router';

@inject(Router)
export class MyClass {
    ...
}

If you look at the actual implementation for the inject decorator in the Aurelia codebase here you will notice that a class property called inject is being assigned on the class here.

Because decorators in Aurelia are optional and nothing more than convenient shortcuts, you can write the above like this:

import {Router} from 'aurelia-router';

export class MyClass {
    static inject = [Router];
}

Let’s create a simple decorator that adds a property to our class called isAwesome a boolean property which will get set on the class itself.

@isAwesome(true)
export class MyClass {

}

function isAwesome(val) {
    return function(target) {
        target.isAwesome = val;
    }
}

In the context of this decorator, target is the class we are using the decorator on and gives us access to the class itself, including the prototype object.

Creating an Aurelia decorator

The above decorator is quite simple. It adds a property to our class and does not do anything exciting. Now, we are going to be creating a decorator which shorthands the Aurelia router lifecycle method canActivate.

function canActivate(val, redirectTo = '') {
    return function(target) {
        target.prototype.canActivate = () => {

            if (!val) {
                if (redirectTo === '') {
                    window.location.href = '/404';
                } else {
                    window.location.href = redirectTo;
                }
            }

            return val;
        };
    };
}

While this is a very rough decorator that would need some improvement before serving a genuine purpose, it showcases how you can modify a class, even adding new methods to the prototype with ease.

Now, let’s clean it up and make it more useful and delightful to look at using some nice new Javascript syntax.

const canActivate = (resolve) => {
    return (target) => {
        target.prototype.canActivate = () => {
            return resolve();
        };
    };
};

Now, we have to pass through a function which allows us to be more flexible in what we can pass through. Still, it could be a lot more useful. What if we wanted to access the current route or get passed in parameters like we can with a class defined method?

const canActivate = (resolve) => {
    return (target) => {
        target.prototype.canActivate = (params, routeConfig, navigationInstruction) => {
            return resolve(params, routeConfig, navigationInstruction);
        };
    };
};

Okay, now we have a decorator which accepts a callback function and has access to the route parameters, the routeConfig and current navigation instruction.

To use our new fancy decorator, we pass through a function which needs to return a value (boolean, redirect):

@canActivate((params, routeConfig, navigationInstruction) => {
    return !(routeConfig.auth);
})
export class MyClass {

}

Apply this decorator will deny the class getting activated if the route has an auth property of true. We inverse the boolean check when we return it.

Just when you thought we couldn’t improve our decorator anymore, you might have noticed there is a flaw in what we have created. It always assumes that our callback returns something. If it doesn’t, we’ll stop the view-model from executing.

Let’s tweak our decorator slightly:

const canActivate = (resolve) => {
    return (target) => {
        target.prototype.canActivate = (params, routeConfig, navigationInstruction) => {
            let resolveCall = resolve(params, routeConfig, navigationInstruction);

            return typeof resolveCall !== 'undefined' ? resolveCall : true;
        };
    };
};

We still require a callback function, but if the developer doesn’t return anything from their callback function, we’ll return true as to ensure the view-model executes fine.

If you wanted to redirect all visitors to a different route if it’s an authenticated route, you could do something like this:

import {Redirect} from 'aurelia-router';

@canActivate((params, routeConfig, navigationInstruction) => {
    return (routeConfig.auth) ? new Redirect('/robots') : true;
})
export class MyViewModel {

}

You would want to add in some additional logic to check if a user is logged in and then redirect accordingly, our example does not accommodate for this. We have just showcased how easy it is to write a decorator which can leverage existing methods and properties, as well as defining new ones.

Creating a decorator that sets the title based on the current route

When it comes to setting the title of the page based on the current route, it can be confusing for newcomers. So, using what we have learned, we are going to create a decorator which allows us to set the title from within a view-model in an Aurelia application.

We want to create a class decorator which hooks into the activate method and accesses the routeConfig, which contains the current navigation model and a method for setting the title.

Our decorator should support passing in a function which returns a string value or the ability to pass in a string directly.

const setTitle = (callbackOrString) => {
    return (target) => {
        ((originalMethod) => {
            target.prototype.activate = (params, routeConfig, navigationInstruction) => {
                let newtitle = typeof callbackOrString === 'function' ? callbackOrString(params, routeConfig, navigationInstruction) : callbackOrString;
                
                if (newtitle !== null && newtitle) {
                    routeConfig.navModel.setTitle(newtitle);
                }

                if (originalMethod !== null) {
                    originalMethod(params, routeConfig, navigationInstruction);
                }
            };
        })(target.prototype.activate || null);
    };
};

One important thing to note is our callback function (if one is passed in) gets the same arguments that the activate method does. This means we get parameters, the current route configuration and navigation instruction.

Using it

Assuming you have imported the decorator above or it exists in the same file as your view-model, let’s show how this decorator is used.

Callback function

We pass in a function which returns a string. This scenario might be helpful if you want to determine if the current user is logged in and display their name in the title.

@setTitle((params, routeConfig, navigationInstruction) => { return 'My Title'; }) 
export class MyViewModel {

}

String value

Passing in a string value will just set the page to this string without the use of callback functions. Useful for pages which don’t need dynamic titles.

@setTitle('My Title') 
export class MyViewModel {

}

Conclusion

In this article, we didn’t even cover the full scope of what you can do with decorators. We have only just scraped the surface. In future articles, we might explore other types of Javascript decorators. All you need to remember is decorators are functions which “decorate” whatever they’re being used with.

As a further exercise, maybe think of other things you can write decorators for, to save you some time.

Further reading

GitKraken “Could not find a compatible repository” Error Fix

I recently encountered an error in GitKraken after a bad merge occurred when trying to merge in some changes from the main development branch, whilst I had quite a few local changes that GitKraken usually automatically stashes for me.

My problem was I was using Bash Ubuntu on Windows, which has a nasty habit of locking files. The merge and stashing seemed to fail because in the changes I was attempting to merge in, some files were deleted.
I tried closing and reopening GitKraken, but it was clear that GitKraken wasn’t going to let me open up that repo again.

The fix

I realise this is a bit of a nuclear fix, but you’ll need to open up PowerShell to fix this. For me, it was simply a matter of navigating to the project directory and running: git reset --hard however, if you need changes, your repo will be interactable just fine on the command line.

As far as I could see with everything I tried, GitKraken won’t ever fix itself, the command line is the only solution. The above, once I ran it and opened up GitKraken it worked just fine again as nothing had happened.

The State of JS Survey Is A Farce: Part Two

Recently, I published a blog title which I titled, The State of JS Survey Is A Farce in which I expressed criticism that the State of JS survey is highly inaccurate, biased and dangerous.

I didn’t get a roaring response until a developer who is one of three running the survey Sasha Greif out of nowhere expressed feelings that I was unkind in my blog post in a Tweet that tagged me.

@AbolitionOf calling the State of JS a “farce” was pretty unkind. I hope you get better treatment if you ever launch your own projects

Admittedly, this Tweet took me by surprise. When I wrote the post, I couldn’t have told you if you asked me who runs the survey. And my intention wasn’t to put down someone else’s work, it was to call out what I saw was bias in a survey growing in popularity.

I was critical, but I never resorted to personal attacks or name-calling. It was strictly criticism and valid criticism (or so I thought). As someone who actively participates in open source myself, I know all too well what unconstructive criticism looks like, but this wasn’t one of those times (at least, not intentionally).

I responded to Sasha on Twitter with the following:

Sorry, you took it personally, Sasha. It was never personal and I apologise if you think otherwise. I just have a problem with biased data being used to turn front-end development into a schoolyard popularity contest by declaring winners and losers.

I apologised and clarified that my post wasn’t personal, it was a criticism of the survey itself and the fact it was trying to turn front-end development into a popularity contest. Sasha didn’t like my response and blocked me without responding.

A few hours later, Sasha unblocked me and sends me a few responses, one of which was the following:

Well in any case I can’t wait for part two of your post where you actually explain why you think the data is biased

I can be pretty blunt, sometimes brutally honest, but one thing I would never do is personally attack someone and their projects for no reason. I have no reason to pick fights or put down others online, I am not a bully, I am a developer too.

My blog post was only criticism of the survey and the data, the data of 20,000 participants, not the people collecting and sorting the data. It’s like blaming the outcome of an election on the people counting the ballot papers.

I can understand that maybe Sasha and his team are proud of the survey which explains why I was met with such hostility, but honestly as I said in my previous blog post, it’s a good idea, it just needs better data.

I thought Sasha’s comment about a follow-up where I explain why I think the data is biased was fair, so here is the follow-up where I will do my best to explain why the data is biased and how it can be fixed.

At a glance: how does data become biased?

Before we proceed, I am not a statistics expert nor do I have professional experience in this field. However, just because this isn’t my realm of expertise doesn’t mean I am unqualified, because the bias is as clear as day in this survey.

Bias in data can come from a lot of things, but in the case of the State of JS survey, in particular, I believe it comes down to:

  • Survey questions that have been worded in a particular way to get a specific/inaccurate result result
  • The data is heavily skewed towards specific countries and excludes a wide variety of demographics, particularly non-English speakers
  • Data has been grouped into misleading categories
  • The team behind the survey mostly all use ReactJS and have a vested interest in its success and market position

Language Bias

Let’s go from the top here. While participants in the survey came from a wide variety of countries, there is some obvious bias here, most of the survey participants came from the USA.

What American developers get to use, is widely different than what developers in say India or South America get to use. One of the fastest growing economies in the world China only had 75 participants and India had 521 participants.

I worked for a company in 2014 that was building a Netflix type streaming video platform for the South American market. We were constrained by needing to support IE8 and AngularJS 1.3 dropped support for IE8, so we were forced to stay on the version prior. This meant we couldn’t use the latest and greatest, internet speeds were also slower and devices had lower specs.

Living in a first-world country, developers are spoiled for choice. Some of us only have to support IE11 minimum now, some of us don’t have to support IE at all. It’s easy to forget the entire world isn’t living in the future or has the latest technology like countries such as the USA is fortunate to have.

Region limitations aside, a huge piece of bias in the survey is that it is only available in one language: English. The lack of translation for other languages such as; Mandarin, Spanish, Arabic is a huge barrier for participants considering Mandarin is the worlds most popular language and English is the third.

As you will see further down, the exclusion of certain countries (due to only being in English) yields interesting results from underrepresented countries.

Solution

Translate the survey into more languages. The survey excludes a very large portion of the world population by only being available in English.

Marketing and Reach: Selection bias

The survey is predominately marketed on Reddit, Twitter, Hacker News and Product Hunt. If you participated in surveys from previous years, you probably got an email. From the outset (because I don’t have the figures), it appears most of the traffic seems to come from social media.

There is a huge problem here: countries like China are more strict in terms of what their citizens can see and do on the internet, social media is notoriously locked down in China. In fact, Twitter, Google, and Reddit are all banned in China.

This explains why China only had 75 participants, chances are you if you live in China you don’t even know this survey exists. If you don’t speak English, you also probably never heard of the survey or did and could not participate.

Solution

Don’t assume that everyone uses social media or can access it. Also, don’t assume that all developers visit Hacker News or other websites. This is a harder problem to crack, but one that maybe partnering with a larger company can solve (such as Google or StackOverflow). The reach and accessibility of the survey needs to be improved.

Angular v AngularJS (miscategorised and slanted questioning )

Unlike previous years (2016 and 2017), the 2018 survey when it came to questions about Angular really shit the bed (so-to-speak) in how it polled developers.

Angular is the newer version (2+) and AngularJS is the older version (< 2). Previous years made the distinction between old Angular and new Angular, however in 2018, the distinction was not made and it essentially invalidated this entire portion of the survey.

While the newer version of Angular is the recommended choice for new projects, not everyone has the luxury of throwing out what they have and starting from scratch (because it can be expensive for starters).

The survey appears to have erroneously made the assumption that AngularJS has been deprecated and abandoned by Google, when AngularJS 1.7 has a long term support (LTS) period of three years that only began July 1, 2018, and expires in 2021.

A lot of companies are still using AngularJS because their applications work and understand the importance of the wise proverb, “If it ain’t broke, don’t fix it.” comes into play here.

This appears to have caused confusion in the survey data. While some can discern the difference between Angular and AngularJS when presented with both options, when presented with just one, it appears they’re both being lumped together and this skews the data.

A popular video on YouTube titled State of JavaScript – Real Analysis of Angular, React, and Vue which currently has almost 30,000 views challenging the State of JS results on its treatment of Angular and claims of its death. This video has 1.5k upvotes, but the real story is in the comments section.

But the backlash doesn’t stop there. Angular core team member Olivier Combe took to Twitter to dispute some of the data in the survey as well. In this Tweet exchange with Sasha, Olivier writes:

Why not make the distinction like the previous years? The complete analysis is worthless because of this. Of course a large number of people wouldn’t use AngularJS again, but that’s not necessarily the case for Angular. If you can’t make a non-biased analysis, don’t do it

In a further reply, Olivier goes on to say:

It’s just basic statistics: don’t compare things if you changed the referential between each data point. Being aware of it is even worse you’re admitting that the data is wrong and yet in the final conclusion about frameworks you say that it won’t be a top-end framework ever again

Once again, we have someone else calling out the bias (albeit a specific part of the survey) and one of the creators of the survey downplaying its significance like it doesn’t matter. This kind of thinking is dangerous and it’s wrong.

Continuing on…

The most telling sign of exclusion bias is shown in the section, Angular Usage by Country. The happiest Angular users are in the most underrepresented countries.

Romania at 58 users makes up 37.9% of the happy camp of Angular users. Egypt at 17 users makes up 35.4% of happy Angular users. New Zealand at 39 users equates to 26.7% of happy Angular users.

Where is this going you ask? Go back to the Participation by Country section and count how many participations from those countries there were in the survey overall.

Romania which had the highest percentage of happy Angular users made up just 0.76% of the survey with a total of 153 participants. This gives us a total of 36.64% of Romanian participants are using Angular and are happy with it.

Now Egypt, only 48 users participated in the survey making a tiny 0.24% of the overall participant count. Now, interestingly the second highest count of happy Angular users above at 17 makes 35.41% of happy Angular users.

Finally, New Zealand had a total of 146 participants and makes up 0.72% of the survey. New Zealand fairs slightly lower, but out of all participants, 26.71% are happy Angular users.

I know large New Zealand companies such as TradeMe.co.nz are big Angular users amongst other New Zealand companies who use Angular. It seems to be used a bit over there, which for a small country is quite impressive.

There are a lot more underrepresented countries who are using Angular and quite happy with it. I only picked a couple of them, but I recommend you go check out the data yourself.

But this seems to somewhat align with the StackOverflow developer survey results for 2018. Even though, StackOverflow targets a more broad audience and has a larger number of participants, we see developers still love working with Angular and are clearly using it (54.6%).

Solution

Questions about Angular and AngularJS should be separate until after the LTS for AngularJS 1.7 ends in 2021 at the very least. The data is also skewed because the participants who were the happiest with Angular were among the least represented in the survey, increasing representation would help address this.

The team behind the survey

For the record, I think this is worth including, but it’s not the primary factor here for why I believe the data in the survey is heavily biased. All three people behind the State of JS survey work with React and so, naturally, anyone who follows them and what they’re working on probably falls into the React camp.

One of the people behind the survey and the one who called me out on Twitter over the previous blog post Sasha Greif actually seems to run an Open source self-described full-stack React+GraphQL framework.

One of the other State of JS members is Raphaël Benitte who has a dashboard tool built with Node, React and D3 called Mozaïk as well as another project os DataViz components built using D3 and React.

Finally, Michael Rambeau runs a site called bestofjs, which seems dominated heavily by React content. On the left-hand side under the popular tags, React has 189 tagged articles and Vue has 50.

Solution

The very fact that two of the three owners of the State of JS survey are heavily invested into React introduces bias because of their followers most likely leaning into React as well, and the only solution here is to introduce more data into the survey so this eventually this is not an issue anymore.

Conclusion

My initial blog post was not personal, and it was not intended to be an attack on Sasha or anyone who runs the State of JS survey.

Reiterating what I already said in my previous blog post, there is bias in the data and there is no doubt about that. I invite all criticism and feedback, so if I made a mistake or assumption in this post, please let me know so I can correct it.

If the team behind the survey simply acknowledged some of these biases when presenting the results, I would not have published my blog post in the first place.

When you take tainted data and you use it to besmirch the name and reputation of frameworks, libraries and tools and tell people to avoid using frameworks like Ember and that Angular is dying, that kind of schoolyard popularity contest bullshit is not needed in an already heavily politicised industry.

I think the State of JS survey is great and it’s the first of its kind, but the data needs to be more random and widespread. The language being used also needs to be less about “us vs them” or “avoid using this” and instead just focusing on displaying the data for what it is and let people draw their own conclusions.

I hope in 2019 we see a more representative and less exclusionary survey that yields more truthful results than what we were given in 2018. I want to see this survey succeed.

Announcing My New Book: Mastering Aurelia Store

I have been working with Aurelia Store these past few months and at one point, I decided that it would be a great idea to write a book on how to leverage the Aurelia Store plugin in your Aurelia applications.

I have been writing on and off for a while and the book now has enough content in it, that I am ready to announce the book. The book is just over 40% complete and keeping in line with how LeanPub operates, the book is a constant work in progress that will be published often. At present, I am publishing once per day.

This means you are buying a work in progress book, but I can tell you the information in it right now will help you if you’re looking to learn how to integrate Aurelia Store into your Aurelia applications as well as work with the underlying RxJS functionality of the store itself.

The book includes many working demos and source code already, and future chapters will equally have a tonne of demos and source code. I am the kind of developer who learns faster with example code, and I know many are the same.

If you have ever been curious how you go about implementing state management into an Aurelia application, or maybe have tried using existing solutions like Redux or MobX and found them intimidating, Aurelia Store is for you.

Buy the book here on LeanPub and pay what you want.