9 of the best JavaScript frameworks

Best for:

  • Simple applications with 
little setup
  • Developing alongside 
web standards

Aurelia is a JavaScript client framework for web, mobile and desktop. It's written with next-gen ECMAScript, integrates with Web Components and has no external dependencies. 

Read on for two mini-tutorials, showing you how to change how properties display value and function, and how to use Aurelia to check values in forms. 

01. Use value converters

Sometimes, when developing components, the values being stored do not lend themselves well to being displayed in a view. A Date object, for example, has an unhelpful value when converted to a string, which requires developers to make special conversion methods just to show values correctly.

To get around this problem, Aurelia provides a mechanism to use classes to change values, known as value converters. These can take any kind of value, apply some kind of processing to it, and output that changed value in place of the original. 

They work similar to pipes in Angular or filters in template languages like Twig.

<input type="text" value.bind="value | capitalise" />

Most will be one way – from the model to the view. But they can also work the other way. The same logic applies, but by using fromView instead of toView, values can be adjusted before they are returned back to the model. 

A good use-case for this would be to format user input directly from the bind on the element. In this example, it will capitalise every word that is entered, which may be useful for a naming field.

<li repeat.for="task of tasks | filter | sort">

They can also be chained together, which encourages the creation of composable converters that can have different uses across the application. One converter could filter an array of values, which then passes to another that sorts them.

<li repeat.for="task of tasks | filter:done">

Converters can also be given simple arguments that can alter the way they behave. Instead of creating different converters to perform similar filtering, create one that takes the type of filter to be performed as an argument. While only one argument is allowed, they can be chained together to achieve the same effect.

02. Try framework-level form validation

Validation is an important part of any application. Users need to be putting the correct information into forms for everything to work correctly. If they do not, they should be warned of the fact as early as possible.

While validation can often be a tricky process, Aurelia has support for validating properties built right into the framework. As long as form values are bound to class properties, Aurelia can check that they are correct whenever it makes sense to the application.

import { inject } from 'aurelia-framework';
import { ValidationControllerFactory, ValidationRules } from 'aurelia-validation';
@inject(ValidationControllerFactory)
export class ValidationForm {
  constructor(controllerFactory) {
    this.controller = controllerFactory.createForCurrentScope();
  }
}

Aurelia provides a ValidationController, which takes instructions from the class, looks over the associated properties and supplies the template with any checks that have failed.

ValidationRules
  .ensure('firstName')
    .required()
    .withMessage('first name required')
.on(ValidationForm);

Each controller requires a single ValidationRules class that defines what's to be checked. These are all chained together, which enables the controller to logically flow through the checks dependant on the options that are passed.

Each ruleset begins with a call to ensure(), which takes the name of 
the property being checked. Any commands that follow will apply 
to that property.

Next are the rules. There are plenty of built-in options like required() or email() that cover common scenarios. Anything else can use satisfies(), which takes a function that returns either a Boolean or a Promise that passes or fails the check.

After the rules come any customisations of that check, for example the error message to display. Rules provide default messages, but these can be overridden if necessary. 

Finally, calling on() applies the ruleset to the class specified. If it is being defined from within the constructor of the class, it can be called with this instead.

this.controller.validateTrigger = validateTrigger.manual;

By default, validation will be fired whenever a bound property's input element is blurred. This can be changed to happen either when the property changes, or it can be triggered manually.