Announcing The Aurelia 2 Book

Buy the Aurelia 2 book here.

With the Aurelia 2 alpha coming very shortly, I have had plans for a while to write another Aurelia book, this time around on Aurelia 2. I learned a lot writing my first book and admittedly, made a few mistakes. The learning experience was invaluable.

With my first book, it came at a time when the Aurelia documentation was subpar. The book served as more of a stand-in for the lack of detailed and concise documentation. With Aurelia 2, extensive documentation work has been undertaken to the point where a book telling you about every little thing makes no sense.

The Aurelia 2 documentation which is updated regularly can be found here if you are wondering where it is located.

This time around, I wanted to write a book that is different from the first, something fun. So, I set out one night to start writing the Aurelia 2 book, not really having a clear goal in mind and after a couple of days, I had one.

The book will touch upon the fundamentals without parroting the documentation too much, it will support TypeScript and you will build an application using Aurelia 2 to get acquainted. The app you will be building is an online cat pictures store, where you can buy pictures of cats.

What You’ll Learn

  • How to generate a new Aurelia 2 app from scratch
  • How to configure Aurelia 2, globalising resources and including plugins
  • How to work with the new direct router
  • How to structure your Aurelia apps
  • How to adopt a component-driven mindset to developing complex UI’s
  • How to leverage new Aurelia 2 features and API’s
  • How to write unit tests using Jest as well as mocks
  • How to test Aurelia 2 components, staging them, querying HTML
  • How to write end-to-end tests with Cypress

The book aims to go beyond just being solely about Aurelia 2, giving you practical skills.

What You’ll Build

An online store for selling cat pictures. It’ll have a homepage, category page, a detail page, a checkout screen and logged in/logged out functionality as well. An accompanying local server running SQLlite will allow your app to feel real as things are persisted.

The application will touch upon how you can add in authentication, how you can create routes, creating secured sections and other fundamentals that will translate across to actual real-world applications.

By the end of the book you’ll have a semi-real online store driven by Aurelia on the front-end, complete with tests and all. The idea is you’ll learn Aurelia 2 by building an application piece-by-piece.

A Work In Progress

Please be aware that the book structure is still being finalised, chapters added and moved around. There will be typos, mistakes in the code and possibly even things that change in Aurelia 2 itself which get removed or added to the book.

As Aurelia 2 evolves in development, so too, will the book. For the entire life of Aurelia 2, the book will be updated in step to remain an up-to-date resource. You only purchase once and all future updates to the book are free.

Buy the Aurelia 2 book here.

GitHub Was Never About Fun

A few days ago I came across an article by Jared Palmer titled GitHub isn’t fun anymore besides the somewhat clickbait-y title he talks about the changes that GitHub has made to the trending section and how GitHub doesn’t feel fun any more.

Sure, the trending page is a cool little gimmick section where you can see popular repositories (or used to be able too), but GitHub was never about fun or non-code features. GitHub is a tool.

Since Microsoft acquired GitHub they have introduced a lot of great new features, one of which I find extremely useful is GitHub Actions. The code review workflow is awesome, protected branches, free private repositories and more.

Why does everything have to be gamified? I am 32 and part of a generation that has short attention spans and inability to do mundane tasks. Like children, my generation seemingly needs instant gratification, karma, scoreboards, points and other features to keep us engaged.

The way that trending used to work was too easily gamed and did not necessarily mean the quality of the repos was good. I am glad they changed how it works, how it works now is properly more indicative of popularity than the previous way it worked.

If you think GitHub isn’t fun, you should try Bitbucket, it is terrible and literally the worst source management platform around. You’ll know what funless really feels like using Bitbucket where projects go to die.

How To Deploy Aurelia 2 Apps To GitHub Pages (gh-pages)

You have yourself an Aurelia app (or you will soon), and you want to host it on GitHub Pages because GitHub provides a generous free hosting solution that gets powered from the Git repository itself.

Fortunately, the process couldn’t be more straightforward. A lot of this post will apply to other frameworks and libraries besides Aurelia 2. However, we will be focusing on Aurelia 2 only.

This article assumes the following:

  • You already have a Git repository for your Aurelia project
  • You are using GitHub to host your Git repository

Create a new branch

We need to create a new branch called gh-pages which GitHub will load our site from. If you use the command line, first run git branch gh-pages followed by git checkout gh-pages to switch to the gh-pages branch. If you’re using a GUI, follow the appropriate steps to create a new branch and switch to it.

Modify .gitignore

If you used the recommended way to initialise a new Aurelia 2 application, your .gitignore file by default will ignore the dist folder where your project files are built.

Inside of this file remove the entry ignoring dist and save it. Now commit and push your changes to the repository.

Build & Deploy

Building your Aurelia 2 application is a simple matter of running npm run build (or appropriate build command) which will then build the files into the dist directory.

Once the build has completed, all you need to do is push up the changes to the dist folder to the gh-pages branch and GitHub will serve them at the following URL https://github-username.github.io/my-repo — where github-username is your GitHub username and my-repo is the name of your repository on GitHub.

To push the contents of the dist folder run the following: git subtree push --prefix dist origin gh-pages and visit your site to see it in its deployed glory.

Fixing The Certbot Issue “The client lacks sufficient authorization/404 Not Found…”

I am a huge fan of Let’s Encrypt and their free SSL certificate service using Certbot. However, recently whilst setting up a new domain name and attempting to get a certificate, I encountered an error I had never experienced before.

The client lacks sufficient authorization :: The key authorization file from the server did not match this challenge

It couldn’t access the folder where it stored the secrets and was resulting in a 404 error. I manually created the folder and I could access it, so why Certbot couldn’t was a mystery.

After some investigation and dead-end Googling, I found the problem and fixed it. I use Linode for my hosting and use the default DNS entries option when adding a new domain.

Well, it turns out by default Linode will add IPv6 AAAA entries to the server and if you do not have Nginx configured to handle IPv6, it will not resolve properly.

It looked something like this:

The culprit was the second entry for the domain with the weird value 2400:8902::f03c:91ff:fe59:f74c this is an IPv6 address and unless you have your server configured to support them, it’ll result in an error when trying to create an SSL certificate.

The fix ends up being rather simple. Either update your server to support those types of addresses or remove the IPV6 entries from your DNS settings and make sure you wait a good 10-20 minutes before trying again.

Ditching Travis CI For GitHub Actions

I have been using Travis CI for my continuous workflow needs for a very long time now. It does what it does and it does it well. However, Travis is an additional service you have to configure and login to, it is a bit disjointed from the code itself.

When GitHub announced Actions, it was a game-changer. Essentially, it was Travis CI embedded into GitHub itself. Over time, the community have run with GitHub Actions and now there are numerous “recipes” to do tasks inside of your actions.

When the feature was first announced and released, it had some teething issues. I actually gave up on GitHub Actions after running into issues I just didn’t bother working around and stuck with the tried and tested Travis CI.

Fast forward to now and I have begun switching over my own projects to use GitHub Actions as well as numerous Npm packages and open-source projects I contribute too are also equally making the switch.

To me, one of the biggest drawcards of GitHub Actions is they are coupled to the repository itself. I try and reduce the number of external dependencies in my projects as much as possible (within reason).

In the past, I have run into issues configuring Travis CI. I once struggled getting Travis CI setup to rsync some files via SSH to a remote server, spending hours upon hours trying to use the Travis CLI to generate an encrypted file in the format it expects .enc I eventually got there, but it as painful.

Ironically, I recently was tasked with creating a build in GitHub Actions that deployed via SSH and it was easy, using a script from the marketplace, I had it all working in five minutes. You can store the private key itself inside of a secret (which is not visible to anyone).

I was never doing anything overly complicated in Travis CI, so I doubt I will notice any difference switching over. The speed of GitHub Actions does seem to be faster (in both spin up and build time), so that is a huge plus.

How To Generate An SSH Key and Add The Public Key To A Remote Server

The thing with SSH authentication is I can never remember the steps to generate an SSH key, and then add that SSH public key to the remote server so SSH authentication works.

I had all of this in a text file, but honestly, I reference my own blog for knowledge on how to do things all of the time, I thought I’d write up a quick post.

You can find numerous blog posts on this, but I always seem to find a straightforward explanation to give me what I need, that I just consulted my text file on my desktop.

Generating An SSH Key

This will generate both private and public keypairs.

ssh-keygen -t rsa -b 4096 -C "johnsmith@gmail.com"
# Generates a new private and public keypair, using the email as the label

You’ll be asked to enter a keyphrase. Personally, I don’t use keyphrases for my keys (I know I probably should). So, I skip the following.

Enter passphrase (empty for no passphrase):
Enter same passphrase again:

For the key names, by default it’ll generate id_rsa and id_rsa.pub but you can name these whatever you want. Because I am dealing with CI providers like Travis CI and GitHub Actions, I generate keys every time I do something with a server.

Add Your Public Key To The Remote Server

Basically, we copy the contents of the public key and store it in the authorized_keys file in the .ssh folder on the server.

cat ~/.ssh/id_rsa.pub | ssh username@domain.com 'cat >> ~/.ssh/authorized_keys'

If you kept the default name, keep id_rsa.pub as the key name. For username@domain.com add in your server username and the server domain name or IP address. The second string part just copies the contents of the file into the authorized_keys file on the server.

How To Add Feature Flags Into Your Javascript Applications

Feature flags are a great way to prevent stale branches by regularly shipping features in your code without officially enabling them. A feature flag let’s you turn code on and off, in the case of features, a feature flag means you can regularly merge branches and release them.

While there are many different ways you can approach this, one of my favourite and most simple approaches is a features.json file in your application.

It can be something as simple as a JSON file of properties and boolean values.

{
    "feature1": true,
	"feature2": false
}

Or in the case of something more flexible and less straightforward it can be something like this where we can specify specific roles who are allowed to use a certain feature.

{
    "feature1": {
        "roles:" ["admin", "editor"]
        "enabled": true
    },
    "feature2": {
        "enabled": false
    }
}

In your code, you import the features.json file and then reference the features. Depending on your framework or environment, this will look different.

import features from './features.json';

const FeatureOne = features.feature1 ? import ('./features/feature-one') : null;

If you were to do this in a framework like Angular or Aurelia, you would create a service or middleware of some kind which compares the route against the property in your features file and reacts accordingly.

import features from './features.json';

export class FeatureService {
    getFeature(key) {
        return features?.[key] ?? null;
    }
}

There are a few feature flag services out there which provide SDK’s and ways to turn features on and off, do A/B testing, but for most use-cases, you don’t need anything else other than a JSON file and a little code to wire it all up.

How To Do Prepared Statement LIKE With SQLlite 3 and The Better SQLite 3 Package

I love SQLite and I am using it in my Aurelia 2 book for the server aspect to provide users with a real server backed by a database. I am using the equally brilliant Better SQLite 3 library which allows you to work with SQLite 3 databases in a performant and easy way.

This is how I did a prepared statement for my LIKE query which searched products by title in my database. The statement itself needs LIKE ? and then on the all method we provide the argument.

Using the template literal syntax with backticks, we handle our wildcard syntax and value in there. You can use whatever pattern you want here, but my use case needed %${query}%

const db = sqlite('mydatabase.db');

const rows = db.prepare(`SELECT * FROM products WHERE title LIKE ?`).all(`%${query}%`);

It’s simple and it works beautifully. Presumably, this would also work for other SQLite 3 libraries, but I highly recommend the Better SQLite 3 library for working with SQLite databases.

How To Get Last 4 Digits of A Credit Card Number in Javascript

Recently whilst working on my Aurelia 2 book, for the example application where you checkout I needed to add in the ability to provide a card number and when it saves, the last 4 digits of the card number get saved.

This is one of those things that as developers we won’t do too often, but it’s easy using substr to trim a text string to a certain length.

let ccNumber = '4560265043620583';
let lastFourDigits = ccNumber.substr(-4);

By providing -4 as the value to substr you’re telling it to take the last 4 characters from the string. The result from our example will be 0583. You can also provide non-negative numbers to go from the beginning as well.

I am sure there are other ways of doing the same thing, but I always look for the easiest to read and easiest to understand solutions and substr fits the bill nicely.

Level Up Aurelia Store With pluck and distinctUntilChanged

Aurelia Store is a powerful state management library for your Aurelia applications, but behind-the-scenes it merely wraps the powerful RxJS observable library. This means you can use a plethora of RxJS methods to change how Aurelia Store works.

Problem: Aurelia Store will fire all state subscribers regardless of change

Whenever your state changes, all listeners of the state object will be fired. While smaller applications won’t introduce any noticeable differences, as your application grows in size and complexity, depending on what you’re doing inside of those store subscribers you can run into some issues.

Sometimes you only want code to run inside of an Aurelia Store subscription if it needs too, akin to some kind of if statement that checks if the code needs to be run.

For example, if you have a isLoading property in your store that changes depending on whether or not something is loading, any code that watches this property should only fire when it changes, not whenever the store’s state changes. Why should isLoading checks care if you’ve loaded a bunch of users or products data?

Solution

Using the RxJS methods pluck and distinctUntilChanged, we can tell our subscriptions to only fire if a specific property in our store has changed. The pluck method allows us to tell RxJS to only watch a specific property in our state object. For the above loading example, we would want to “pluck” the isLoading property pluck('isLoading').

Lastly, we want to use the distinctUntilChanged method which accepts no arguments. All it does is takes our “plucked” value and compares it to its previous value to see if it changed or not.

import { distinctUntilChanged, pluck } from 'rxjs/operators';

this.store.state.pipe(pluck('isLoading'), distinctUntilChanged()).subscribe((isLoading) => {
    // The isLoading property changed
});

Now, this works great for most use cases. However, as documented in the distinctUntilChanged the documentation details a caveat on how the check works you need to be aware of.

distinctUntilChanged uses === comparison by default, object references must match!

If you want to do a check based on an object property, you need to use the distinctUntilKeyChanged method which is not covered in this post.

Really, that is all there is to it. You pluck a property and then you do a distinct check to react whether or not the value has changed. This is all just RxJS code and nothing overly Aurelia Store specific. There are a tonne of other RxJS operators you should read up on.