Note: This is the core version of adhere. It contains only the essentials making it easy to understand what adhere does.
Check out the common version of adhere. It contains functions your are likely to need in your projects.
What?
Adhere in essence allows you to compose filters. As you will see in the examples, this can be very powerful. Adhere also allows you to provide default values or coerce objects.
Basics
Lets say we have a data object that looks like this:
var person = name: 'Mick' tags: 'energetic' 'gamer' address: street: 'Christiaan Huygenslaan' number: 5916
We would like to validate this object. So we would normally write a function:
{ if person === false throw 'Expected person to have property name' if typeof personname !== 'string' throw 'Expected person.name to be a string' if person === false throw 'Expected person to have property tags' if is === false throw 'Expected person.tags to be an array' persontags // and so on ...}
You can already see that there will be a lot of duplicate code which creates a nice environment for copy-paste and other bugs. How would we solve this with adhere? We write small transforms that do a small portion of validation for us, similarly to many assertion libraries.
var adhere = // A transform that throws an error when it does not receive a string. { if typeof value === 'string' return value throw 'Expected a string'} // A transform that throws an error when it does not receive a number. { if typeof value === 'number' return value throw 'Expected a number'} // Create person transform using adhere's functions. var validatePerson = adhereobject name: string tags: adhere address: adhereobject street: string number: number // Execute the new validation function. console // Will log the object after having passed through all the transforms.
We have now used both adhere.object
and adhere.array
.
The function adhere.object
allows you to create a filter for an object. In this case we create a transform that expects an object with three properties: 'name', 'tags' and 'address'. These properties are validated using the basic string
and number
transforms and the composed transforms (using adhere.array
and adhere.object
in this case).
The function adhere.array
returns a transform that maps each item in the to-be-validated-array using the passed transform.
The core version of adhere supports a third composition function called pipe
. As you might expect, pipe
creates a new transform from a sequence of transforms. The return value of the first transform is passed second transform. The return value of the second transform is passed to the third and so on.
We can use it like so:
var adhere = { if typeof value === 'string' return value throw 'Expected ' + JSON + ' to be a string'} { if typeof value === 'number' return value throw 'Expected ' + JSON + ' to be a number'} { if object return value throw 'Expected ' + JSON + ' to have own property ' + key + '.'} adhereobject name: adhere tags: adhere address: adhere
Improving readability
To improve readability, adhere.object
and adhere.pipe
can be called implicitly. The last example can be written as:
adhereobject name: own string tags: own adhere address: own street: own string number: own number
There is less fuss around the things that matter but you need to know what is going on to really understand it.
Transforms
By now you might have asked yourself: 'Why don't we use boolean functions as validators?' You mean like this?
{ return typeof value === 'string'}
While it would have been possible for adhere to accept these kinds of functions, it limits the possibilities. Adhere accepts exception based validators of which the return value replaces the passed value. I like to call these functions transforms. With transforms we can:
- throw informative errors and
- change the value.
See the following transform for example:
{ if object return value throw 'Expected ' + JSON + ' to have own property ' + key + '.'}
Defaults
You could implement default values using a simple transform:
{ return { return typeof value === 'undefined' ? defaultValue : value }}
Coercion
To force a value into an array, you could use the following transform:
{ return is ? value : value }