A Conventional Blog for Convention Based Coders

Author: jason

I read someone’s question on SO asking “How do I add a day to my date?”. Well it occurred to me that there’s really not enough information in that question to give a proper answer, and it’s not only a classic example of the importance of separating data from presentation information, but also an excellent example of understanding requirements and potential mishaps in seemingly simple situations.

Firstly, it’s important to note that 24 hours later is not always the same as “this time tomorrow“. Daylight savings causes some quite serious problems, because one day each year we have no times existing between 2am and 3am, and six months later we have the same hour occurs twice on the same day!!

So what if I set a backup to run at 2:30 am every day? What will happen on 1 April here in Melbourne? Well, if we rely on local time format the backup will execute twice.

So what about 7 Oct 2018? Our backup will never run, because 2am-3am ceases to exist.

OK, so this is a bit of a simplistic set of statements, because we know we would look to see if it was after 2:30am, so that would probably fix 1st April, but even then, the double whammy on 7th October is an issue.

The fact is that DST handling is a presentation factor, not a data one. The underlying data value in a Date object is an integer with a count of the number of milliseconds since midnight on 1/1/1970. But anything we display or parse using the Date() object will by default be handled in local time, unless we specifically tell it to use UTC (GMT) timezone.

So just be sure to differentiate between UTC and local times. All maths should be done on the UTC time, and all presentation can be done on local times where Date (or moment.js/date-fns) converts the date (for leap years) and hours (for DST), and even 30 minutes for timezones on half-hour adjustments.

Working in local time introduces some rather serious issues. Since the clock go forward for us on 7 Oct 2018 at 2am, what happens if I try to set Date() to be 2:30am? Well you get a rather confusing behaviour:

1

2

3

4

5

6

newDate('2018-10-07T01:30:00')

Sun Oct07201801:30:00GMT+1000(Local Standard Time)

newDate('2018-10-07T02:30:00')

Sun Oct07201803:30:00GMT+1100(Local Daylight Time)

newDate('2018-10-07T03:30:00')

Sun Oct07201803:30:00GMT+1100(Local Daylight Time)

Performing the same type of manipulation with UTC times shows the relationship between the UTC time and local time properly (notice the Z on the end to indicate UTC or GMT):

1

2

3

4

5

6

newDate('2018-10-06T15:30:00Z')

Sun Oct07201801:30:00GMT+1000(Local Standard Time)

newDate('2018-10-06T16:30:00Z')

Sun Oct07201803:30:00GMT+1100(Local Daylight Time)

newDate('2018-10-06T17:30:00Z')

Sun Oct07201804:30:00GMT+1100(Local Daylight Time)

But, back to the original question, how do I add a day? Well, do I want to add 24 hours, or one day? One day sounds simple, but what if it’s 2:30am March 31st? Which of the 2:30ams do I set it to the next day?

It’s critical to understand the usage of time periods in applications, and it’s advisable to use relative times wherever possible, as they are fixed numeric deltas that can be applied to the UTC representation of the current time, regardless of timezone.

So essentially, make sure you always store and manipulate data using UTC based functions, and not local time, otherwise you open yourself up to a whole world of confusion and pain. I always recommend people persist all data in UTC format, and supply all data to all objects in UTC format, allowing those objects and/or views to render those times in whatever format they require.
Use a library such as momentjs or date-fns to simplify manipulating your dates, but beware of code bloat as some of these libraries include all the locale data and strings, so make sure you trim them down to the locales you require.

It’s sometimes helpful to know in code if a validation has been performed, or if an individual field has changed its state.

While there are no events currently raised by the ValidationController, we can add our own thanks to some rather snazzy built-in features of Aurelia.

If you’ve read my posts in Gitter, you may have noticed me ranting on about the Event Aggregator, and how frustrated I get at it being misused by people as an event queue, while in reality it’s a very simple pub-sub service. Well in this case the fact that it is simply a pub-sub service is perfect for our needs.

When @jdanyow pointed me to the Event Aggregator code for event handling, my first comment was that the global application doesn’t need to know about every event, only those in the scope of the validation controller, then he pointed out this fascinatingly simple little piece of code:

Now this is awesome. This is a drop-in pub-sub handler re-using the event aggregator, intended for use at a local scope level. At the end of the day the default EventAggregator is exactly the same, implemented as a singleton for our entire application, but that simple instruction lets us inject event handling into any object instance we create.

Almost… unfortunately this is tricky for TypeScript because this code is injecting functions onto an object instance, and people will also argue that this is an anti-pattern, because you’re morphing someone else’s code, but at least it exposes the fact that new instances of Event Aggregators can be used anywhere… so let’s just extend the base EventAggregator class, and use that.

So, let’s apply it to the validation service!

Now where can we go to hear every time validation is performed? A validation Renderer! This is called for every render operation, and is passed in all of the information regarding the result, including the messages, related UI elements, and the reason for the change (this is not yet published, but should be in the next day or so).

So do we want to hack our existing renderer do add this? Well we could, or we could simply add a new instance, as the controller allows us to attach as many renderers as we like.

OK, so let’s create a custom renderer to raise out events:

event-renderer.js

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

exportclassEventRendererextendsEventAggregator{

render(instruction){

this.publish('validate',instruction);

for(let{error,elements}of instruction.unrender){

for(let element of elements){

this.publish('hide',{element,error});

}

}

for(let{error,elements}of instruction.render){

for(let element of elements){

this.publish('show',{element,error});

}

}

}

}

Then we’ll add it to our controller, along with the usual one we want to display our errors, and while we’re at it we’ll add a few subscriptions to monitor various events occurring in the controller:

Remember though that these events can be used to detect changes visually on the screen, but can’t be used to indicate the overall validity of a form, as some errors may be for field with rules which have not yet been validated, as the user has not yet tabbed through or form-validated.

One additional nice feature is that the result above shows 6 ‘render’ errors, but only 5 listed. So where’s the 6th? Well that’s a validation rule against a field that has no UI element, so in my implementation I’m not raising a ‘show’ event. But the error is available through the ‘validate’ event, and if you wanted you could easily generate an additional event for those ‘hidden’ failures:

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

for(let{error,elements}of instruction.unrender){

if(!elements.length)

this.publish('hide-non-ui',{null,error});

else

for(let element of elements){

this.publish('hide',{element,error});

}

}

for(let{error,elements}of instruction.render){

if(!elements.length)

this.publish('show-non-ui',{null,error});

else

for(let element of elements){

this.publish('show',{element,error});

}

}

Oh, and don’t forget to dispose of your EventAggregator when you’re finished!

The return value from subscribe is function called dispose() that closes the subscription, and without this call your VM may be left sitting in memory (and may continue to react to published events)

But please don’t go overboard on use of the Event Aggregator! It has its uses, but it is not a message queue, it is one-way only, and I’ve seen it abused far too many times as a communications mechanism between units.

It’s worth noting that function such as required() and maxLength() are simply helpers that point to a predefined satisfies functions, showing that the same features used by rules defined in the library are also available to you in your validation definitions.

So what about when it’s a one-off simple validation rule, not requiring a re-usable generic custom rule? Well there’s even a syntax for that through use of the satisfies() fluent function:

JavaScript

1

2

3

.ensure((m:App)=>m.firstname).displayName("First name")

.required()

.satisfies(v=>v.trim()===v).withMessage('${$displayName} cannot have leading or trailing spaces.')

And to top it all off, both satisfies and custom rules support the return of a Promise for async validation calls, such as making server calls to test username uniqueness, or validating email addresses against existing lists.

Predicates

Sometimes you only want to apply a set of rules if a certain condition has been met in your model. This is referred to as a predicate expression, and one example might be to only validate an email address if the user reports that they want to subscribe to the newsletter:

JavaScript

1

2

3

.ensure((m:App)=>m.email)

.required().when((m:App)=>m.newsletter===true)

.email().when((m:App)=>m.newsletter===true)

This is particularly important when you consider that in this case you may be hiding or excluding the input field if the user is not subscribed to the newsletter, but the validation rule will still be applied because the rule is against the object, not the UI field!
Note that the when condition applies to each rule, and not the overall ‘ensure’ block. This allows finer grain control, albeit it at the expense of slightly more verbose code.

Well the obvious thing is simply style them, but we have some useful additional data available via the controller, such as the control that is linked to the property that was bound to the rule that failed validation…

So we can see from this that the validation controller exposes a Map linking visual elements to validation failures, so we can simply find the first associated element and set focus to that DOM element.
It’s not perfect, as there can be cases where a rule has no visual element, but it will suffice for this demonstration.

So we make sure the template is globally registered:

JavaScript

1

config.globalResources(['./elements/validation-summary.html'])

and we include it at the bottom of our form:

XHTML

1

2

3

4

5

<validation-summary

errors.bind="controller.errors"

controller.bind="controller"

autofocus.bind="true">

</validation-summary>

What do we get? This piece of awesomeness:

You may have noticed this in the middle of the template:<template replaceable part="error">${error.message}</template>

This lets us replace the string with an alternative format in the host view:

Over the last 12 months or so Aurelia has had two different approaches to validation offered as official packages. The first was innovative and reasonably effective, but the code-base was a bit messy, and the original team-member dropped off the map, leaving the team in a tricky situation.

The decision was then made to create a simple interface so that developers could plug in any back-end validation they liked, and an example was created using the Validate.js library. This survived for a few months, but there were many issues related to the underlying engine that made it unsuitable as a solution for the long-term.

Other libraries exist, including Treacherous, which I wrote about here, and this is still available as an option. Now, after many hours of meetings with Jeremy Danyow of the Aurelia core team, we’ve managed to pull in all of the ideas and use-cases learned from these other systems into what we hope is one of the most complete validation solutions out there, let-alone the best for Aurelia.

So let’s take the new version for a spin!

Note that this is example written in Typescript, but if you’re daft enough to sacrifice all that nice type-checking and intellisense and want to use ES6, all you need to do is remove the :type from things (e.g. firstname: string = ''; becomes firstname = '';) and change constructor(private controller: ValidationController) { to say constructor(controller) { this.controller = controller;

The documentation will all be on the Aurelia Hub within the next few hours, but let’s create a really simple example of its use on a form. We’ll start with a simple CLI project, and bodge a simple example into the main form.

First, don’t forget to add aurelia-validation as a plugin in our main.ts, as this is needed even if you’re not using the UI bindings:

JavaScript

1

.plugin('aurelia-validation');

Next, let’s setup the ValidationController and create some rules in our main VM:

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

import{inject,NewInstance}from'aurelia-framework';

import{ValidationRules,ValidationController}from"aurelia-validation";

@inject(NewInstance.of(ValidationController))

exportclassApp{

message='';

firstname:string='';

lastname:string='';

constructor(private controller:ValidationController){

ValidationRules

.ensure((m:App)=>m.lastname).displayName("Surname").required()

.ensure((m:App)=>m.firstname).displayName("First name").required()

.on(this);

}

validateMe(){

this.controller

.validate()

.then(v=>{

if(v.length===0)

this.message="All is good!";

else

this.message="You have errors!";

})

}

}

Now we have to do two things in our view. We have to tell the validator which fields we would like to link to the UI for validation, and we’d like to display the list of validation errors on-screen:

XHTML

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<template>

<div>

<p> Firstname: <input value.bind="firstname & validate"/></p>

<p> Lastname: <input value.bind="lastname & validate"/></p>

</div>

<button click.delegate="validateMe()">Validate</button>

<h3>Latest validation result: ${message}</h3>

<ul>

<li repeat.for="error of controller.errors">

${error.message}

</li>

</ul>

</template>

OK, so now we have an extremely unexciting form, but it’s actually pretty powerful. When the form opens the error list is empty, but as we tab over each field the validation engine applies our rules against the associated property (which it found following the Binding), but it only applied the rule when the field lost focus.
It is possible to have the validation fire on every change, on blur, or only manually, and this can be set at a ValidationController level and on a per-field basis.

So we now have everything to test and display errors.

So what if we want to have the errors displayed on a per-field basis?

Well this is highly solution-centric, as the validation system doesn’t know if you want to use Bootstrap 3.0 errors, roll-your-own, or simply change the colour of a field. Even if you simply want to change colour, what class would you like assigning to the input element?

So we now have the option of adding as many validation renders as we like. They take a really simply set of parameters, and you can perform as much DOM manipulation as you like, including making your renders conditional based on information regarding the rule or the associated input element.

Here’s a very simple one to add a class to an element, and to add a DIV element with the message:

The Aurelia validation stuff is very much in a state of flux, as it has been for the last 14 months, so I started looking for an alternative.

There are lots of validation libraries around, and they all have their own peculiarities and foibles. One thing that is clear from the libraries currently available is that there seems to be a clear difference of opinion over business rules vs form input validation. Most libraries work on UI form inputs, while a few work on the underlying model itself. So why does it matter?

Well if we’re doing UI validation, we’re (hopefully) providing timely feedback when something is obviously not adhering to some requirement we’ve set. It might be invalid characters, a number too big or small, or a blank field where the value is mandatory. These are simple, obvious requirements which every validation system must support.

But what happens when we have a business rule validation? Not all business rules require massive processing operations, but by definition they sit at the business-end of the connection, and are often either centrally maintained, or at the very least they require data from a business-owned repository. For example, is this username already in use? Has the user entered a postcode that the postal service doesn’t recognise?

Then we have the question of whether or not to validate an object itself. If we want to ensure that the user has entered data into no more than three of the five possible input fields, who owns that rule? Which input field does it belong to? Where would we display the error message? If we retrieve an object’s data from the server, and we only allow the user to edit their name, what if the postcode was invalid in our central repository? Do we refuse to let the user save their data, saying “Invalid postcode”, when the user has no means of updating it?

These are just a few of the types of issues we have to consider in creating a validation solution that covers most users’ requirements. No validation solution will meet every requirements, but whatever we end up with it *must* be flexible enough to be adapted to meet all the edge cases, and there are always a lot of edges to any solution!

After writing my own validation solution, I discovered that a clever chap called Lee (@grofit) had already done one that encapsulated most of the features mine did. Given that his coding is so much better than mine, I decided to use his as the base, and simply contribute to that where I could.

The key differentiator between this and the current validate.js based Aurelia solution is the use of async validation rules, which means each rule can take as long as necessary to resolve, and every rule follows the same pattern. Validate.js has a very bodged-on solution to address async functionality, and it doesn’t play nicely when you separate the rule definitions from their usage. I believe that all rules should follow the same pattern, allowing you to modify rules at any time without changing the calling interface.

So how does Treacherous work? Well, essentially you define a set of rules (of which about 15 are predefined), then you assign those against a property in a model by name, and you specify the message to display if it fails. It’s not perfect, but it’s the closest I’ve found so far, and is relatively easy to extend where necessary.

Are being driven nuts by the following error message when compiling a webpack aurelia project?

Error: No module factory available for dependency type: ContextElementDependency

Be driven no longer! The issue is usually caused by a dependency version not matching the parent version.

NPM, awesome as it is, has the annoying feature of not updating child dependencies when you execute npm update. All of the top-level packages will be updated, but the child ones will not.
Some packages, such as aurelia-templating-bindinghave a dependency on aurelia-binding, and while both are generally released together, aurelia-bindingis not typically defined as a top level package, so it doesn’t get updated when the parent does.

What happens when we want to bind to something that returns a Promise?

Well, if we have a Promise in our viewmodel we get an extremely unhelpful display of [object Promise] on the screen, because by default we will see the string representation of the returned value.

The first time most people develop with Promises they ask “How do I get my return value?”. Well, the truth is that you never do when you call a Promise. All you ever get back is a Promise, but that Promise is guaranteed to run a piece of code that you provide (which is why it’s called a Promise!).

So, if Aurelia asks us for a value on-screen, but we don’t have one right now, can we ask it to sit and twiddle its thumbs until we’re ready? No.

So, how about if we were to say “OK, look, I’ll get it for you, and you tell me what you want me to do with it and I’ll do that when I get it”?
Now that sounds perfect!

So what we want to do is ask Aurelia what it uses to write the value into the DOM, intercept that, don’t initially bother doing it, but do it later on when the Promise we’re interested in has resolved! Easy! (ish)

In fact, instead of just not doing it for now, we could optionally display something like ‘Busy…’ while we wait. Cool stuff.