Skip to content

breeze-client / Validator

Class: Validator ​

Defined in: src/validation/validate.ts:201

Instances of the Validator class provide the logic to validate another object and provide a description of any errors encountered during the validation process. They are typically associated with a 'validators' property on the following types: EntityType, DataProperty or NavigationProperty.

Property-level validators normally arrive with the metadata. The Breeze server sends a validators array for each data property - for example required for a non-nullable property, maxLength for a string with a maximum length, and a data-type validator such as int32 or date. They are not inferred on the client, so metadata written by hand has none unless you add them.

To write your own, construct one with a name, a validation function and a context. Several basic "Validator" construction methods are also provided as static methods to this class. These methods provide a simpler syntax for creating basic validations.

Many of these stock validators are inspired by and implemented to conform to the validators defined at http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx

Sometimes a custom validator will be required.

Examples ​

ts
Most validators will be 'property' level validators, like this.
ts
// v in this function is the value to be validated, in this case a "country" string.
    const valFn = (v: string | null) => v == null || v.startsWith("US");
    const countryValidator = new Validator("countryIsUS", valFn, {
        displayName: "Country",
        messageTemplate: "'%displayName%' must start with 'US'"
    });

    // Now plug it into Breeze.
    // Assume em1 is a preexisting EntityManager.
    const custType = em1.metadataStore.getAsEntityType("Customer");
    const countryProp = custType.getProperty("country");
    // Note that validator is added to a 'DataProperty' validators collection.
    countryProp.validators.push(countryValidator);
Entity level validators are also possible
ts
function isValidZipCode(value: string) {
        const re = /^\d{5}([\-]\d{4})?$/;
        return re.test(value);
    }

    // the value in this case will be a Customer entity
    const valFn = (cust: Customer) => {
        // This validator only validates US Zip Codes.
        if (cust.country === "USA") {
            return isValidZipCode(cust.postalCode);
        }
        return true;
    };
    const zipCodeValidator = new Validator("zipCodeValidator", valFn,
        { messageTemplate: "For the US, this is not a valid PostalCode" });

    // Now plug it into Breeze.
    // Assume em1 is a preexisting EntityManager.
    const custType = em1.metadataStore.getAsEntityType("Customer");
    // Note that validator is added to an 'EntityType' validators collection.
    custType.validators.push(zipCodeValidator);
What is commonly needed is a way of creating a parameterized function that will itself
return a new Validator.  This requires the use of a 'context' object.
ts
// create a function that will take in a config object
    // and will return a validator
    const numericRangeValidator = (context: { min?: number, max?: number }) => {
        const valFn = (v: any, ctx: ValidationMessageContext) => {
            if (v == null) return true;
            if (typeof v !== "number") return false;
            if (ctx.min != null && v < ctx.min) return false;
            if (ctx.max != null && v > ctx.max) return false;
            return true;
        };
        // The last parameter below is the 'context' object that will be passed into the 'ctx' parameter above
        // when this validator executes. Several other properties, such as displayName will get added to this object as well.
        return new Validator("numericRange", valFn, {
            messageTemplate: "'%displayName%' must be a number between the values of %min% and %max%",
            min: context.min,
            max: context.max
        });
    };
    // Assume that freightProperty is a DataEntityProperty that describes numeric values.
    // register the validator
    freightProperty.validators.push(numericRangeValidator({ min: 100, max: 500 }));

Breeze substitutes context values and functions for the tokens in the messageTemplate when preparing the runtime error message;
'displayName' is a pre-defined context function that is always available.

Please note that Breeze substitutes the empty string for falsey parameters. That usually works in your favor.
Sometimes it doesn't as when the 'min' value is zero in which case the message text would have a hole
where the 'min' value goes, saying: "... an integer between the values of and ...". That is not what you want.

To avoid this effect, you may can bake certain of the context values into the 'messageTemplate' itself
as shown in this revision to the pertinent part of the previous example:
ts
// ... as before
    // ... but bake the min/max values into the message template.
    const template = core.formatString(
        "'%displayName%' must be a number between the values of %1 and %2",
        context.min, context.max);
    return new Validator("numericRange", valFn, {
        messageTemplate: template,
        min: context.min,
        max: context.max
    });

Param ​

name

{String} The name of this validator.

Param ​

validatorFn

{Function} A function to perform validation.

validatorFn(value, context)

Param ​

validatorFn.value

{Object} Value to be validated

Param ​

validatorFn.context

{Object} The same context object passed into the constructor with the following additional properties if not otherwise specified.

Param ​

validatorFn.context.value

{Object} The value being validated.

Param ​

validatorFn.context.name

{String} The name of the validator being executed.

Param ​

validatorFn.context.displayName

{String} This will be either the value of the property's 'displayName' property or the value of its 'name' property or the string 'Value'

Param ​

validatorFn.context.messageTemplate

{String} This will either be the value of Validator.messageTemplates[ {this validators name}] or null. Validator.messageTemplates is an object that is keyed by validator name and that can be added to in order to 'register' your own message for a given validator. The following property can also be specified for any validator to force a specific errorMessage string

Param ​

validatorFn.context.message

{String} If this property is set it will be used instead of the 'messageTemplate' property when an error message is generated.

Param ​

context

{Object} A free form object whose properties will made available during the validation and error message creation process. This object will be passed into the Validator's validation function whenever 'validate' is called. See above for a description of additional properties that will be automatically added to this object if not otherwise specified.

Constructors ​

Constructor ​

new Validator(name, valFn, context?): Validator

Defined in: src/validation/validate.ts:231

Creates a validator. See the class description for examples.

Parameters ​

name ​

string

The validator's name. Also the default key of the errors it produces.

valFn ​

ValidationFn

The function that validates: called with the value (or, for an entity-level validator, the entity) and the context, it returns whether the value is valid.

context? ​

ValidationMessageContext

Settings for the validator and its messages, such as displayName and messageTemplate. They are available to valFn and to the error message template.

Returns ​

Validator

Properties ​

context ​

context: ValidationMessageContext

Defined in: src/validation/validate.ts:210

The context this validator was created with, plus name, messageTemplate and a displayName function. It is passed to valFn and used to compose error messages. Read Only


currentContext ​

currentContext: ValidationMessageContext

Defined in: src/validation/validate.ts:212

The context of the most recent call to Validator.validate: context extended with any additional context passed to it. Validator.getMessage reads it. After a validation that passed, it is context again. Read Only


isAsync ​

isAsync: boolean

Defined in: src/validation/validate.ts:222

Whether this validator's function returns a promise: an async function, or one created with isAsync: true in its context. Breeze runs an async validator only when it can wait for the answer - when an entity is saved, and from EntityAspect.validateEntityAsync and EntityAspect.validatePropertyAsync. It does not run on a property change, an attach or a query, where nothing could wait for it; editing the property clears its error instead, as it clears the server's. Read Only


name ​

name: string

Defined in: src/validation/validate.ts:206

The name of this validator, such as required or maxLength. It picks the default message template and forms part of each ValidationError's key. Read Only


valFn ​

valFn: ValidationFn

Defined in: src/validation/validate.ts:208

The function that performs the validation. It returns true if the value is valid. Read Only


bool ​

static bool: () => Validator

Defined in: src/validation/validate.ts:673

Returns a standard boolean data type Validator.

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em1 is a preexisting EntityManager.
    const productType = em1.metadataStore.getAsEntityType("Product");
    const discontinuedProperty = productType.getProperty("isDiscontinued");
    // Validates that the value of the isDiscontinued property on Product is a boolean
    discontinuedProperty.validators.push(Validator.bool());

byte ​

static byte: (context?) => Validator

Defined in: src/validation/validate.ts:659

Returns a standard byte data type Validator. (This is a integer between 0 and 255 inclusive for js purposes).

Parameters ​

context? ​

any

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em1 is a preexisting EntityManager.
    const orderType = em1.metadataStore.getAsEntityType("Order");
    const freightProperty = orderType.getProperty("freight");
    // Validates that the value of the freight property on Order is a byte: an integer from 0 to 255.
    // Probably not a very good validation to place on the freight property.
    freightProperty.validators.push(Validator.byte());

creditCard ​

static creditCard: (context?) => Validator

Defined in: src/validation/validate.ts:730

Returns a credit card number validator Performs a luhn algorithm checksum test for plausability catches simple mistakes; only service knows for sure

Parameters ​

context? ​

any

{Object} optional parameters to pass through to validation constructor

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em is a preexisting EntityManager.
    const personType = em.metadataStore.getAsEntityType("Person");
    const creditCardProperty = personType.getProperty("creditCard");
    // Validates that the value of the Person.creditCard property is credit card.
    creditCardProperty.validators.push(Validator.creditCard());

date ​

static date: () => Validator

Defined in: src/validation/validate.ts:699

Returns a standard date data type Validator.

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em1 is a preexisting EntityManager.
    const orderType = em1.metadataStore.getAsEntityType("Order");
    const orderDateProperty = orderType.getProperty("orderDate");
    // Validates that the value of the orderDate property on Order is a date
    orderDateProperty.validators.push(Validator.date());

double ​

static double: (context?) => Validator = Validator.number

Defined in: src/validation/validate.ts:594

Another name for Validator.number, registered as double so that metadata naming it imports. The validator it returns is named number.

Returns a standard numeric data type Validator.

Parameters ​

context? ​

any

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em1 is a preexisting EntityManager.
    const orderType = em1.metadataStore.getAsEntityType("Order");
    const freightProperty = orderType.getProperty("freight");
    // Validates that the value of the freight property on Order is a number.
    freightProperty.validators.push(Validator.number());

duration ​

static duration: () => Validator

Defined in: src/validation/validate.ts:563

Returns a ISO 8601 duration string Validator.

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em1 is a preexisting EntityManager.
    const timeLimitType = em1.metadataStore.getAsEntityType("TimeLimit");
    const maxTimeProperty = timeLimitType.getProperty("maxTime");
    // Validates that the value of the maxTime property on TimeLimit is a duration.
    maxTimeProperty.validators.push(Validator.duration());

emailAddress ​

static emailAddress: (context?) => Validator

Defined in: src/validation/validate.ts:779

Returns the email address validator

Parameters ​

context? ​

any

{Object} optional parameters to pass through to validation constructor

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em is a preexisting EntityManager.
    const userType = em.metadataStore.getAsEntityType("User");
    const emailProperty = userType.getProperty("email");
    // Validates that the value of the User.email property is an email address.
    emailProperty.validators.push(Validator.emailAddress());

guid ​

static guid: () => Validator

Defined in: src/validation/validate.ts:545

Returns a Guid data type Validator.

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em1 is a preexisting EntityManager.
    const custType = em1.metadataStore.getAsEntityType("Customer");
    const customerIdProperty = custType.getProperty("customerID");
    // Validates that the value of the customerID property on Customer is a Guid.
    customerIdProperty.validators.push(Validator.guid());

int16 ​

static int16: (context?) => Validator

Defined in: src/validation/validate.ts:644

Returns a standard 16 bit integer data type Validator.

Parameters ​

context? ​

any

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em1 is a preexisting EntityManager.
    const orderType = em1.metadataStore.getAsEntityType("Order");
    const freightProperty = orderType.getProperty("freight");
    // Validates that the value of the freight property on Order is within the range of a 16 bit integer.
    freightProperty.validators.push(Validator.int16());

int32 ​

static int32: (context?) => Validator

Defined in: src/validation/validate.ts:630

Returns a standard 32 bit integer data type Validator.

Parameters ​

context? ​

any

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em1 is a preexisting EntityManager.
    const orderType = em1.metadataStore.getAsEntityType("Order");
    const freightProperty = orderType.getProperty("freight");
    freightProperty.validators.push(Validator.int32());

int64 ​

static int64: (context?) => Validator = Validator.integer

Defined in: src/validation/validate.ts:619

Another name for Validator.integer, and the data-type validator for DataType.Int64: it checks that the value is a whole number, with no range check. The validator it returns is named integer.

Returns a standard large integer data type - 64 bit - Validator.

Parameters ​

context? ​

any

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em1 is a preexisting EntityManager.
    const orderType = em1.metadataStore.getAsEntityType("Order");
    const freightProperty = orderType.getProperty("freight");
    // Validates that the value of the freight property on Order is within the range of a 64 bit integer.
    freightProperty.validators.push(Validator.int64());

integer ​

static integer: (context?) => Validator

Defined in: src/validation/validate.ts:608

Returns a standard large integer data type - 64 bit - Validator.

Parameters ​

context? ​

any

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em1 is a preexisting EntityManager.
    const orderType = em1.metadataStore.getAsEntityType("Order");
    const freightProperty = orderType.getProperty("freight");
    // Validates that the value of the freight property on Order is within the range of a 64 bit integer.
    freightProperty.validators.push(Validator.int64());

makeRegExpValidator ​

static makeRegExpValidator: (validatorName, expression, defaultMessage?, context?) => Validator

Defined in: src/validation/validate.ts:861

Creates a regular expression validator with a fixed expression. Many of the stock validators are built with this factory method. Their expressions are often derived from https://github.com/srkirkland/DataAnnotationsExtensions/blob/master/DataAnnotationsExtensions You can try many of them at http://dataannotationsextensions.org/

Parameters ​

validatorName ​

string

{String} name of this validator

expression ​

RegExp

{String | RegExp} regular expression to apply

defaultMessage? ​

string | null

{String} default message for failed validations

context? ​

any

{Object} optional parameters to pass through to validation constructor

Returns ​

Validator

A new Validator

Example ​

ts
// Make a zipcode validator
    const zipValidator = Validator.makeRegExpValidator(
        "zipVal",
        /^\d{5}([\-]\d{4})?$/,
        "The %displayName% '%value%' is not a valid U.S. zipcode");
    // Register it.
    Validator.register(zipValidator);
    // Add it to a data property. Assume em is a preexisting EntityManager.
    const custType = em.metadataStore.getAsEntityType("Customer");
    const zipProperty = custType.getProperty("postalCode");
    zipProperty.validators.push(zipValidator);

maxLength ​

static maxLength: (context) => Validator

Defined in: src/validation/validate.ts:485

Returns a standard maximum string length Validator; the maximum length must be specified

Parameters ​

context ​

any

An object with maxLength (number).

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em1 is a preexisting EntityManager.
    const custType = em1.metadataStore.getAsEntityType("Customer");
    const regionProperty = custType.getProperty("region");
    // Validates that the value of the region property on Customer will be less than or equal to 5 characters.
    regionProperty.validators.push(Validator.maxLength({ maxLength: 5 }));

messageTemplates ​

static messageTemplates: Record<string, any>

Defined in: src/validation/validate.ts:430

Map of standard error message templates keyed by validator name. You can add to or modify this object to customize the template used for any validation error message.

Example ​

ts
// v in this function is the value to be validated, in this case a "country" string.
    const valFn = (v: string | null) => v == null || v.startsWith("US");
    const countryValidator = new Validator("countryIsUS", valFn, { displayName: "Country" });
    Validator.messageTemplates.countryIsUS = "'%displayName%' must start with 'US'";
    // This will have a similar effect to this
    const countryValidator2 = new Validator("countryIsUS", valFn, {
        displayName: "Country",
        messageTemplate: "'%displayName%' must start with 'US'"
    });

none ​

static none: () => Validator

Defined in: src/validation/validate.ts:682

Returns a Validator named none that accepts every value. It is the data-type validator for DataType.Binary and DataType.Undefined.

Returns ​

Validator


number ​

static number: (context?) => Validator

Defined in: src/validation/validate.ts:583

Returns a standard numeric data type Validator.

Parameters ​

context? ​

any

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em1 is a preexisting EntityManager.
    const orderType = em1.metadataStore.getAsEntityType("Order");
    const freightProperty = orderType.getProperty("freight");
    // Validates that the value of the freight property on Order is a number.
    freightProperty.validators.push(Validator.number());

phone ​

static phone: (context?) => Validator

Defined in: src/validation/validate.ts:814

Returns the phone validator Provides basic assertions on the format and will help to eliminate most nonsense input Matches: International dialing prefix: one of nothing, +, 0 or 0000 (with or without a trailing break character, if not '+': [-/. ])

ts
((\+)|(0(\d+)?[-/.\s]))

Country code: nothing, or 1 to 999 (with or without a trailing break character: [-/. ])

ts
[1-9]\d{,2}[-/.\s]?

Area code: (0) to (000000), or 0 to 000000 (with or without a trailing break character: [-/. ])

ts
((\(\d{1,6}\)|\d{1,6})[-/.\s]?)?

Local: one or more digits (with or without a trailing break character: [-/. ])

ts
(\d+[-/.\s]?)+\d+

Parameters ​

context? ​

any

{Object} optional parameters to pass through to validation constructor

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em is a preexisting EntityManager.
    const customerType = em.metadataStore.getAsEntityType("Customer");
    const phoneProperty = customerType.getProperty("phone");
    // Validates that the value of the Customer.phone property is phone.
    phoneProperty.validators.push(Validator.phone());

regularExpression ​

static regularExpression: (context?) => Validator

Defined in: src/validation/validate.ts:753

Returns a regular expression validator; the expression must be specified

Parameters ​

context? ​

any

An object with expression (string) - String form of the regular expression to apply.

Returns ​

Validator

A new Validator

Example ​

ts
// Add validator to a property. Assume em is a preexisting EntityManager.
    const customerType = em.metadataStore.getAsEntityType("Customer");
    const regionProperty = customerType.getProperty("region");
    // Validates that the value of Customer.region is 2 char uppercase alpha.
    regionProperty.validators.push(Validator.regularExpression({ expression: '^[A-Z]{2}$' }));

required ​

static required: (context?) => Validator

Defined in: src/validation/validate.ts:462

Returns a standard 'required value' Validator

Parameters ​

context? ​

any

An object with allowEmptyStrings (boolean) - If this parameter is omitted or false then empty strings do NOT pass validation.

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em1 is a preexisting EntityManager.
    const custType = em1.metadataStore.getAsEntityType("Customer");
    const regionProperty = custType.getProperty("region");
    // Makes "region" on Customer a required property.
    regionProperty.validators.push(Validator.required());
    // or to allow empty strings
    regionProperty.validators.push(Validator.required({ allowEmptyStrings: true }));

single ​

static single: (context?) => Validator = Validator.number

Defined in: src/validation/validate.ts:596

Another name for Validator.number, registered as single so that metadata naming it imports. The validator it returns is named number.

Returns a standard numeric data type Validator.

Parameters ​

context? ​

any

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em1 is a preexisting EntityManager.
    const orderType = em1.metadataStore.getAsEntityType("Order");
    const freightProperty = orderType.getProperty("freight");
    // Validates that the value of the freight property on Order is a number.
    freightProperty.validators.push(Validator.number());

string ​

static string: () => Validator

Defined in: src/validation/validate.ts:527

Returns a standard string dataType Validator.

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em1 is a preexisting EntityManager.
    const custType = em1.metadataStore.getAsEntityType("Customer");
    const regionProperty = custType.getProperty("region");
    // Validates that the value of the region property on Customer is a string.
    regionProperty.validators.push(Validator.string());

stringLength ​

static stringLength: (context) => Validator

Defined in: src/validation/validate.ts:506

Returns a standard string length Validator; both minimum and maximum lengths must be specified.

Parameters ​

context ​

any

An object with maxLength (number); minLength (number).

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em1 is a preexisting EntityManager.
    const custType = em1.metadataStore.getAsEntityType("Customer");
    const regionProperty = custType.getProperty("region");
    // Validates that the value of the region property on Customer will be
    // between 2 and 5 characters
    regionProperty.validators.push(Validator.stringLength({ minLength: 2, maxLength: 5 }));

url ​

static url: (context?) => Validator

Defined in: src/validation/validate.ts:831

Returns the URL (protocol required) validator

Parameters ​

context? ​

any

{Object} optional parameters to pass through to validation constructor

Returns ​

Validator

A new Validator

Example ​

ts
// Assume em is a preexisting EntityManager.
    const supplierType = em.metadataStore.getAsEntityType("Supplier");
    const homePageProperty = supplierType.getProperty("homePage");
    // Validates that the value of the Supplier.homePage property is a URL.
    homePageProperty.validators.push(Validator.url());

Methods ​

getMessage() ​

getMessage(): string

Defined in: src/validation/validate.ts:342

Returns the message generated by the most recent execution of this Validator.

Returns ​

string

Example ​

ts
const v0 = Validator.maxLength({ maxLength: 5, displayName: "City" });
    v0.validate("adasdfasdf");
    const errMessage = v0.getMessage();

toJSON() ​

toJSON(): ValidationMessageContext

Defined in: src/validation/validate.ts:371

Returns the serializable form of this validator: its name plus the context it was created with, such as { name: "maxLength", maxLength: 50 }. Breeze uses it when it exports metadata; Validator.fromJSON reads it back through the factory registered under that name.

Returns ​

ValidationMessageContext


validate() ​

validate(value, additionalContext?): ValidationError | null

Defined in: src/validation/validate.ts:265

Run this validator against the specified value. This method will usually be called internally either automatically by an property change, entity attach, query or save operation, or manually as a result of a validateEntity call on the EntityAspect. The resulting ValidationResults are available via the EntityAspect.getValidationErrors method.

However, you can also call a validator directly either for testing purposes or some other reason if needed.

Parameters ​

value ​

any

{Object} Value to validate

additionalContext? ​

ValidationMessageContext

{Object} Any additional contextual information that the Validator can make use of.

Returns ​

ValidationError | null

A ValidationError if validation fails, null otherwise

Example ​

ts
// using one of the predefined validators
    const validator = Validator.maxLength({ maxLength: 5, displayName: "City" });
    // null, because "asdf".length <= 5
    const noError = validator.validate("asdf");
    const result = validator.validate("adasdfasdf");
    // extract all of the properties of the 'result'
    const errMsg = result.errorMessage;
    const context = result.context;
    const sameValidator = result.validator;

validateAsync() ​

validateAsync(value, additionalContext?): Promise<ValidationError | null>

Defined in: src/validation/validate.ts:319

Runs this validator, sync or async, and resolves with a ValidationError if the value is invalid, or null. Each call has a context of its own, so calls may overlap; unlike Validator.validate, it does not set Validator.currentContext.

ts
const ve = await Validator.maxLength({ maxLength: 5 }).validateAsync("adasdfasdf");

A function that throws or rejects gives an error, as it does in validate.

Parameters ​

value ​

any

The value to validate.

additionalContext? ​

ValidationMessageContext

Anything else the validator can use, such as the entity and property.

Returns ​

Promise<ValidationError | null>


fromJSON() ​

static fromJSON(json): any

Defined in: src/validation/validate.ts:379

Creates a validator instance from a JSON object or an array of instances from an array of JSON objects.

Parameters ​

json ​

any

{Object} JSON object that represents the serialized version of a validator.

Returns ​

any


register() ​

static register(validator): void

Defined in: src/validation/validate.ts:400

Register a validator instance so that any deserialized metadata can reference it.

Parameters ​

validator ​

Validator

{Validator} Validator to register.

Returns ​

void


registerFactory() ​

static registerFactory(validatorFactory, name): void

Defined in: src/validation/validate.ts:411

Register a validator factory so that any deserialized metadata can reference it.

Parameters ​

validatorFactory ​

(options?) => Validator

{Function} A function that optionally takes a context property and returns a Validator instance.

name ​

string

{String} The name of the validator.

Returns ​

void

Released under the MIT License.