Skip to content

Instantly share code, notes, and snippets.

@jaidetree
Created August 28, 2018 00:22
Show Gist options
  • Select an option

  • Save jaidetree/dc49e2328b3d9ed25f8712e3f89c03f3 to your computer and use it in GitHub Desktop.

Select an option

Save jaidetree/dc49e2328b3d9ed25f8712e3f89c03f3 to your computer and use it in GitHub Desktop.
An example of a functional-programming inspired validator
import { of } from "rxjs/observable";
import { filter, map } from "rxjs/operators";
import validate, * as v from "libs/validate";
const validateForm = validate([
v.field("name", "Full Name", [
v.isRequired,
"A full name is required.",
name => name.split(" ").length,
wordCount => wordCount < 2,
"Please provide a first name and last name."
wordCount => wordCount > 2,
"Only a first name and last name is required."
]),
v.field("email", "Email", [
v.isRequired,
"An email address is required",
v.isEmail,
"Please provide a valid email address.",
]),
v.field("age", "Your Age", [
v.isNumeric,
"Age must be a numeric value",
// naive, custom isInteger
age => String(age) === String(parseInt(age, 10)),
"Age must be a positive, whole number.",
Number,
age => age >= 62,
"Sorry you are too young to collect social security.",
]),
v.field("favorite_color", "Your Favorite Color", [
v.isRequired,
"A favorite color is required",
color => color === "blue",
"Sorry but your favorite color must be blue.",
]),
]);
const data = {
name: "Amadaeus F. Blundershvlt",
email: "amadaeus@example",
age: 15,
};
of(data)
.pipe(
map(validateForm),
// optional
// filter(form => form.isValid === true)
)
.subscribe(console.log);
// =>
// {
// data: {
// name: "Amadaeus F. Blundershvlt",
// email: "amadaeus@example",
// age: 15,
// },
// isValid: false,
// errors: [
// {
// name: "name",
// label: "Full Name",
// message: "Only a first name and last name is required.",
// },
// {
// name: "email",
// label: "Email",
// message: "Please provide a valid email address.",
// },
// {
// name: "age",
// label: "Your Age",
// message: "You are too young to collect social security.",
// },
// {
// name: "favorite_color",
// label: "Favorite Color",
// message: "A favorite color is required.",
// },
// ]
// }
Promise.resolve(data)
// this is what v.toPromise does but since validateForm is just a function
// you can wrap it so it can be coerced into whatever shape or structure
// you need
.then(data => {
const form = validateForm(data);
return form.isValid
? Promise.resolve(form.data)
: Promise.reject(form.errors);
})
.then(console.log)
.catch(console.error)
// Pass Case
// =>
// {
// name: "Amadaeus Blundershvlt",
// email: "[email protected]",
// age: 63,
// favorite_color: "blue",
// }
// Fail Case
// =>
// [
// {
// name: "name",
// label: "Full Name",
// message: "Only a first name and last name is required.",
// },
// {
// name: "email",
// label: "Email",
// message: "Please provide a valid email address.",
// },
// {
// name: "age",
// label: "Your Age",
// message: "You are too young to collect social security.",
// },
// {
// name: "favorite_color",
// label: "Favorite Color",
// message: "A favorite color is required.",
// },
// ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment