Have I switched to Tailwind?

I’ve never been much of a designer; I know what I like and I can recreate any design a designer passes my way. However, producing anything original is incredibly hard.

I switched to Bootstrap many years ago to help me solve the problem, Bootstrap made it easy to create what I wanted and still have it look OK – typically more than ok.

Bootstrap sites typically look the same and before I go on, I don’t necessarily consider that a “bad thing”. The problem arises when you don’t want everything to look the same. Customisation is possible with Bootstrap, particularly version 5. However, it gets complicated quickly.

I’ve released three Apps in the last year, two game scorers for Yahtzee and Yatzy and Budget, a free open-source budgeting App. The Apps all look ‘similar’, this isn’t necessary a problem because they all belong to the Costs to Expect service so it should be obvious that they belong to the same brand. However, I wanted something different for Budget Pro, an evolution of Budget.

Budget Pro belongs to the same family as all the Apps I released this year but being the paid version, I wanted to differentiate it from Budget and give it a sharpened look. Due to its features, it will also have a more complex UI than Budget. As I was thinking about how to ‘improve’ the Budget design I decided to give Tailwind a go as everything I’ve seen of it has impressed me, particularly Tailwind UI.

Two things pushed me over the edge. Firstly. Tailwind UI, having an extensive library of components to build with and from made it easy to get started and start building up ideas. Secondly, the standalone cli; I don’t want or need any additional dependencies and prefer vanilla JavaScript over any front-end toolchains.

I’m only a little way into my journey with Tailwind but so far, I’m loving it. Yes, you end up with lots of classes in the HTML. However, you know what each of them do based on the name and I create components to reduce duplication anyway.

We’ll see if the honeymoon continues as I move away from landing and content pages and get into the nitty gritty of creating the meat of Budget Pro.

Invokable controllers

For several years I have been a fan of invokable classes, typically to act as action classes for forms and to create jobs for queues etc.

With regards to forms, this works well. The validation and creation code is all contained in one class keeping code out of the controller. If all you need is validation and a little logic before saving/updating, this model works well. The model breaks down when the complexity goes up.

On a recent project, I needed to validate the request, convert the data, generate lots of additional values related to fluid flow and validate again. Only after I have calculated the viability of the submitted data, do I save the request.

My action classes have simple names – createGame, saveUser, – you get the idea. From reading the name of the action, you know what it does and when you look inside, you have an idea about what you will see. This doesn’t work when there are five or six steps that must happen before the “quote” is created.

Invokable controllers to the rescue – I get all benefits of invokable action classes without the negative of a giant action class which is doing more than its name suggests.

I rarely use invokable controllers but when I do, they are a life saver.

Supporting multiple measurement units

I’m working on a freelance project in which there are multiple measurement units. For example, customers can provide their required flow rate in litres per second, litres per minute, litres per hour, cubic meters per hour, gallons a minute or imperial gallons per minute.

Warning: This gets really complicated, fast!

You might have noticed we have imperial and metric measurement units above. Well, that means we need to support mm, meters, degrees Celsius and the inferior imperial versions some people still use. You know who you are.

To try and keep it simple, I have ingress objects which take all values and convert them to a ‘known’ unit of measurement for each type. I can then process all my calculations and not need to be concerned with converting anything whilst I’m calculating. When done, I have egress objects which convert everything back to the required unit and format.

I’m also storing everything in the original format, and I’ve tended to find over the years that this is better than converting and then storing. Customers don’t tend to like it when a value of three returns as 2.99997 next time they look at the request.

I’m only a little way into the project but so far, having a single interface to deal with is making much easier as I only need to care about the units for a value at the time it enters the ‘service’ and the moment it exits the ‘service’ and is about to be presented on screen.

Hopefully, all goes well, only time will tell.

Blog posts on freelance projects are deliberately a little vague as I can’t really divulge too much, I can talk about general stuff but obviously I’m never going to mention specifics.

Jobs and tasks gamble paid off

I have spent the last 12 months developing a product for one of my long-term clients, I’m going to refer to the product as EWAQO for the rest of this post.

I initially thought EWAQO would be three to four months of work, lockdowns, homeschooling, the pandemic in general and feature creep put paid to that.

EWAQO is far from the largest product I’ve worked on, I’ve been a professional developer for over twenty years and have worked at scale, it is however the largest product I’ve created single-handled. The Costs to Expect API, Website and App are big when combined, EWAQO is in a world of its own, it has so many different systems and is immense.

I decided early on to go deep with queues and scheduled tasks, I wanted to keep the App fast for the user and do as much of the heavy lifting as possible behind the scenes. Typically, I’m using queues for complex user-initiated tasks/actions and scheduled tasks are for processing.

It is easy to handle the complex stuff behind the scenes, but there is a problem, you need some visibility. Before I wrote the first job I created the interface, that way the client can see what is happening, is a job running? Did it fail? What was the output? Who initiated it? etc.

This was the masterstroke and made so much of the complexity possible, the client could see what is happening, job classes and tasks are simpler to create because you don’t need to worry about the front-end, it all came together brilliantly.

I’m not done with EWAQO, as of writing, there are 27 jobs and 26 scheduled tasks and I have visibility of each one, I can see when they are running, what is due, when and why they fail, it all just works.

We are working toward the soft-release of Costs to Expect this year, part of that is developing two smallish apps that act as companions. Both apps will borrow heavily from what I learned developing EWAQO.

Dart Sass with Windows Subsystem for Linux (WSL)

This is a minor update to an earlier post; the setup is simpler than previously.

  1. Download and extract the dart-sass release you are going to use, at the time of this post I opted for https://github.com/sass/dart-sass/releases/download/1.26.10/dart-sass-1.26.10-windows-x64.zip
  2. Open your .bashrc file in WSL – vi ~/.bashrc
  3. Add export PATH="/path/to/dart-sass:$PATH" to the end of the file, in my case export PATH="/mnt/c/Users/USERNAME/Documents/GitHub/dart-sass:$PATH"

To test everything is working, open WSL and enter sass --version; you should see the version number.