harriyott.com

The Blog

Beeping Angular

Waiting for Angular to build is boring. I'm using ng build --watch to trigger a build whenever I save a file, but it's hard to know when it's done. I don't like staring at the timestamp waiting for it to change:

Screen shot of Angular build --watch

I compare the time in the window with the actual time in the bottom corner of my screen, but if I'm making small changes, the minute is the same. If I'm distracted, I may look away briefly and miss when the build has finished and find I'm staring at it waiting for it to change, but it just doesn't.

Boggle

I'm a big fan of Boggle, with the exception of the timer. When I'm busy writing words or looking at dice, I don't want to be wasting time glancing at the falling sand. Sometimes we all forget to look, and find that we missed the end, and the timer stopped at some unknown point in the past. I'm sure you all know how infuriating this is. Whenever I play, I set a timer on my phone to beep when the three minutes is up. We can all concentrate, and we get to play with less frustration.

Being as smart as you are, I'm sure you've deduced by now that I wanted the Angular build process to beep when it had finished. The initial problem was that the process wasn't finishing, because the --watch flag keeps it running. Had it been a single process, I could have put it in a batch file with an echo ^G afterwards. (Those who didn't spend their teenage years on an Amstrad PC1512 may not know that Ctrl+G is ASCII 7, i.e. BEL (a beep)). You can type echo Ctrl+g into a command prompt to make a beep, which is more pleasing than it should be.

However, there's no post-build hook in Angular (that I could find), so I needed something else. Twelve years ago I discovered C#'s FileSystemWatcher for a project I was working on. It's the only time I've used it, but now was the time to bring it out again. I think of it often, but it sits there in a drawer, waiting for a special occasion, next to my bowtie. A FileSystemWatcher keeps an eye on a file or directory, and if a file changes, it fires an event. My plan was to get this dude to camp out with his binoculars looking at the Angular output directory and if anything happens, send me an E in morse code.

So in a new console app, I lovingly sculpted a new watcher:

When it fires, it makes just the right kind of beep.

I ran it, saved an Angular file, and it beeped when it finished. Several times, in fact, as several files changed. I wanted just the one, so I used a short timer to catch the changes:

This timer delays the beep for 0.3 seconds, and doesn't let any other file changes trigger a new beep in the interim. As an aside, when you're playing Boggle, and you see the word TIMER, it's Levidrome is REMIT, so you can write that immediately. Obviously there's TIME too, whose Levidrome is EMIT, so you've got four words from one without thinking about it.

So now I'm happily coding in Angular in Visual Studio, pressing Ctrl+Shift+S, clicking on the browser window containing the app, hovering my finger over the F5 key, and then staring out of the window until I hear the beep, when I tap the F5 key immediately. Problem solved; happy Simon.

DRY routes between C# and Angular

I have an Angular 5 app talking to a C# api. Having magic strings for the end-points in both the TypeScript and the C# route attributes seems fragile to me:

I wanted a single source of urls, so the first step was to create a C# class of constants and use them in the controller.

Manually typing an equivalent TypeScript class may make the code a fraction less fragile, but it would still be writing the same code twice. Ideally the Angular app would be able to access the C# constants, but there's no direct way. I've been a big fan of code generation over the years, using NimbleText, CodeSmith, Resharper templates and T4. My plan was to generate a TypeScript class from the C# class. I plumped for T4. This uses reflection on the class to get a list of the class's constants containing the urls. It loops round them, checking for parameters, e.g. {kittenId}. If there are any, the template generates a function that accepts the parameters and returns the formatted string. If there are no paramters, then a property is generated instead. The output of this template is included in the Angular app, and is accessible from the rest of the code.

A much less fragile way of linking front- and back-ends through code generation.

Tip for class and property names in SQL queries

A common pattern is using an ORM for writes, and SQL (e.g. via Dapper) for reads. A possible cause of bugs is having SQL in magic strings.

var query = "SELECT DISTINCT TeamName FROM InternatonalPlayers";

There may be a typo in a table or column name, which wouldn't be caught at compile time, or renaming something in the future that causes a database schema change could break the SQL.

To mitigate these problems, I've started using nameof in SQL statements:

var query = $"SELECT DISTINCT {nameof(InternationalPlayers.TeamName)} FROM {nameof(InternationalPlayers)}";

If there's a spelling mistake, the code won't compile. If either the class or property are renamed, the editor will update them automatically, or a compile error will occur.

Why you might not want to do this

Unit or integrating test will catch typos or renames in magic string SQL, but this will occur later than compile time.

It makes the SQL longer. In the example above, you could create a teamName variable for the long property name, which will add another line of code (and possibly blank line for clarity).

Foreign key Id columns may have an _id or Id suffix added by the ORM, which don't appear in the property names. You could add this into the SQL directly after the nameof closing curly brace, but then we've introduced magical stringyness. We could look this up from the ORM configuration, but I'm sure you'll posit that this is going a bit far.

Anyway, there we are. Take it or leave it. HTH.

Possessive apostrophes in C# identifiers

Having a strong inclination towards grammar pedantry precision is both a blessing and a curse. Just now I was irritated with an ambiguous variable name, playersTeams. Is it one playerʼs teams, or many playersʼ teams? The apostrophe placement is important in written English to distinguish (ooh, accidental rhyme!) the number of players referred to.

Pressing the ' key to create an apostrophe in the variable name is obviously disallowed, as it is used in C# to delimit character values:

Single quote

However, that key isnʼt actually an apostrophe - itʼs just used as one for convenience. There is an actual proper Unicode apostrophe character though:


ʼ

This can be used in identifiers, thus:

Apostrophe in identifier

Now Iʼm pretty sure what will happen when this code is reviewed. It does look wrong, and Iʼm not sure if I will actually use it. It does, however, help with one of the hard problems in computer science.

n.b. You can select and copy the big apostrophe above, and paste it into your code editor.

Save

Save

Save

Code Reviews

I started my current freelance role 6 years ago. I created an intranet, which I have been expanding and maintaining mostly by myself. Recently, a new senior developer has joined the team, as a permanent member of staff. During the induction process we discussed how we should work together, and decided early on that code reviews would be useful. They would enable me to check that he's using the existing (well, legacy to him) code in the right way, and secondly to ensure the code he produces is of suitable quality.

The notion of suitable quality is somewhat subjective, so we talked at length how we could make it more objective. There are horror stories about code reviews causing tensions between coders, and we wanted to avoid starring in our own. Having objective ways to assess the code under review would help.

We also agreed that the code was under review, not the coder, so any perceived criticism need not be taken personally.

The objective criteria we came up with are:

  • The code should compile and run
  • The unit tests should all pass
  • The code should implement the specification
  • The coding standards have been adhered to
  • The code is SOLID

Being objective, this allows us to write code in our own personal style; after all, there are many ways to solve the same problem. So long as the criteria are met, the code is acceptable.

I decided that my code should be reviewed too. For years I've been working mostly alone with no review process, and it would do the codebase and me some good. This meant a bit of source control reconfiguration; I used to code on the main github repo, but now I have a fork that I develop on, and submit pull requests to the main repo for review. The github pull request and code review process is really good (with the possible exception of a feisty red cross icon against any comment).

Well, so far it's going well. As we know our code will be reviewed, we run through the checklist before submitting the pull request, so the code is already improved before the review starts. There have been no major infractions: most of the requested changes have been typos, suggested renamings, the odd tabs / spaces inconsistency. There was one small but clear bug; I think a less than that should have been a greater than or something like that; a code review is a much cheaper place to find it than on the live site.

The best moments so far though, have been when noticing small code smells. This has led to a couple of good conversations discussing what the problem might be (they weren't immediately obvious), and suggesting possible refactorings. After a bit of recoding, the resubmitted code was leaner, more SOLID, more readable, and just plainly better. If it wasn't obvious beforehand, it certainly was afterwards.

In all, I'm really pleased with how the code reviews have been going. I feel more confident about the codebase, and my coding skills. I've learnt a couple of new things from reading every line of someone else's code too, which is a side-effect I hadn't anticipated.