Validation

import Validation from 'dataparcels/Validation';
import Validation from 'react-dataparcels/Validation';
Validation(ValidatorMap) => PartialParcelBoundaryConfig;

Dataparcels’ Validation plugin provides an easy way to test whether data conforms to a set of validation rules. Once configured, it provides function that can be run against Parcel data, and it will set Parcel meta wherever data is invalid.

Example usage

Please refer to the UI Behaviour page to see a full example.

const validation = Validation({
    'name': validateStringNotBlank("Name"),
    'animals.*.type': validateStringNotBlank("Animal type"),
    'animals.*.amount': [
        validateInteger("Animal amount"),
        validatePositiveNumber("Animal amount")
    ]
});

// example validator
const validateStringNotBlank = (name) => (value) => {
    return (!value || value.trim().length === 0) && `${name} must not be blank`;
};

// usage

ParcelBoundary({
    name: 'exampleParcel',
    hold: true,
    modifyBeforeUpdate: [validation.modifyBeforeUpdate]
    // ^ run validator before data updates
    //   to set meta on Parcels that have failed validation
});

Arguments

ValidationMap

ValidationMap = {
    [matchPath: string]: ValidationRule|ValidationRule[]
    ...
};

Validation accepts a single argument, a ValidationMap. A ValidationMap is an object whose values are validation rule functions, or arrays of validation rule functions. The ValidationMap’s keys are strings specifying which paths to run the validator on.

If an array of validation rules is provided, all rules must pass in order for the validation on that value to pass.

ValidationRule

ValidationRule = (value: any, keyPath: Array<any>) => any;

The intent of a ValidationRule is to analyze a value, and if the value does not pass the validation check then data signifying an error must be returned. Usually this is a string containing the error message. If the value passes the check, something falsey should be returned.

Each ValidationRule function is passed the value of the Parcel that is being validated, as well as the Parcel’s keyPath.

Example ValidationRules

const validateStringNotBlank = (value) => {
    return (!value || value.trim().length === 0) && `Value must not be blank`;
};

const validateInteger = (value) => {
    return !Number.isInteger(value) && `Value must be a whole number`;
};

const validatePositiveNumber = (value) => {
    return value < 0 && `Value must not be negative`;
};

matchPath

A matchPath is a string that prescribes where to run each validation rule.

  • The dot character (.) is used to specify the key at the next layer of depth in the data structure.
  • The star character (*) is used as an instruction to apply the rule to all pieces of data at that depth.
let value = {
    person: {
        firstName: "George"
    },
    pets: [
        "Fido",
        "Sniffles"
    ]
};

Validation({
    'person.firstName': validatorRule,
    // ^ when run on value, this will be called once
    // receiving a value of "George"
    'pets.*': validatorRule
    // ^ when run on value, this will be called twice
    // receiving a value of "Fido", then "Sniffles"
})

Return

ValidationResult

ValidationResult = {
    modifyBeforeUpdate: ParcelValueUpdater,
    onRelease: ContinueChainFunction
};

The Validation function returns an object containing two functions.

modifyBeforeUpdate

This is a function that can be used directly with modifyBeforeUpdate on ParcelHoc, ParcelBoundary or ParcelBoundaryHoc.

This will check the Parcel’s value and set Parcel meta wherever validations errors occured.

On each validated Parcel, parcel.meta.invalid will contain undefined if the data is valid, or the result of the validator rule if the data is invalid. This can then be easily rendered.

Please refer to the UI Behaviour page to see a full example.

ParcelBoundary({
    name: 'exampleParcel',
    hold: true,
    modifyBeforeUpdate: [validation.modifyBeforeUpdate]
    // ^ run validator before data updates
    //   to set meta on Parcels that have failed validation
});

onRelease

This is a function that can be used directly with onRelease on ParcelBoundary or ParcelBoundaryHoc.

If release() is called, this onRelease function will prevent the release from taking place if any data is invalid.

ParcelBoundary({
    name: 'exampleParcel',
    hold: true,
    modifyBeforeUpdate: [validation.modifyBeforeUpdate]
    onRelease: [validation.onRelease]
});