For more tips like this, sign up to the weekly newsletter!

Combine validators

Validators are extensively used when dealing with user inputs and data from external sources.

In many cases, you need more than one validator for a given input. In that case, you need to combine multiple validator functions into a single validator.

The easiest case is when each validator gets a string to validate, and outputs a boolean (its signature is (string) => boolean).

For example, the following two functions validate different aspects of numbers:

function isNumeric(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

function isPositive(n) {
  return parseInt(n) > 0;
}

console.log(isNumeric("5"));	// true
console.log(isNumeric("abc"));	// false
console.log(isNumeric("5g"));	// false
console.log(isNumeric("0"));	// true
console.log(isPositive("0"));	// false
console.log(isPositive("abc"));	// false
console.log(isPositive("5g"));	// true

To make a function that validates that a given string is both a number and is positive, use a combine function that outputs true if all the passed validators return true:

const combine = (...fns) => (val) => fns.reduce((memo, fn) => memo && fn(val), true);

And to use it:

const combined = combine(isNumeric, isPositive);

console.log(combined("5"));	// true
console.log(combined("0"));	// false
console.log(combined("5g"));	// false

The combined validator's signature is the same (string) => boolean, making higher-order validators possible:

function lessThan5(n) {
  return parseInt(n) < 5;
}

const evenMoreCombined = combine(combined, lessThan5);

console.log(evenMoreCombined("4"));	// true
console.log(evenMoreCombined("6"));	// false

This way you can create arbitrarily complex validators out of simple ones.

Try it
References
Learn more: