Skip to content

Custom object validator

rsamec edited this page Jul 24, 2014 · 1 revision

Custom object validator

You will learn how to create custom validator for your own object and how to assign validation rules to its properties. You can assigned these rules

  • property validation rules - use RuleFor property
  • property async validation rules - use RuleFor property
  • shared validation rules - use ValidationFor property
  • custom object validator - use ValidatorFor property - enables composition of child custom validators

How to assign property validation rules

Let`s image your object has this structure.

interface IPerson{
    FirstName:string;
    LastName:string;
}

To create validator you have

  • create AbstractValidator object
  • assign some rules to object properties
          //create new validator for object with structure<IPerson>
          var personValidator = new Validation.AbstractValidator<IPerson>();

          //basic validators
          var required =new Validation.RequiredValidator();
          var maxLength = new Validation.MaxLengthValidator(15);

          //assigned validators to property
          personValidator.RuleFor("FirstName", required);
          personValidator.RuleFor("FirstName",maxLength);

          //assigned validators to property
          personValidator.RuleFor("LastName", required);
          personValidator.RuleFor("LastName",maxLength);

Use validator to get validation results

    this.PersonValidator = personValidator.CreateRule("Person");
    var result = this.PersonValidator.Validate(this.Data);
    if (result.HasErrors){
        console.log(result.ErrorMessage);
    }

Test - custom object validator with property validation rule test

describe('simple property validators', function() {

        beforeEach(function(){
            //setup
            this.Data = {};
            this.PersonValidator = personValidator.CreateRule("Person");

        });

        it('fill correct data - no errors', function () {

            //when
            this.Data.FirstName = "Jonh";
            this.Data.LastName = "Smith";

            //excercise
            var result = this.PersonValidator.Validate(this.Data);

            //verify
            expect(this.PersonValidator.ValidationResult.HasErrors).to.equal(false);

        });

        it('fill incorrect data - some errors', function () {

            //when
            this.Data.FirstName = "";
            this.Data.LastName = "Smith toooooooooooooooooooooooooooooooo long";

            //excercise
            var result = this.PersonValidator.Validate(this.Data);

            //verify
            expect(this.PersonValidator.ValidationResult.HasErrors).to.equal(true);
        });

    });

How to assign async property validation rules

Let`s image your object has this structure.

interface IPerson{
    Job:string
}

To create validator you have

  • create AbstractValidator object
  • assign some async rules to object properties
         //create new validator for object with structure<IPerson>
               var personValidator = new Validation.AbstractValidator<IPerson>();

               //async functions returning list of values
               var optionsFce = function() {
                   var deferral = Q.defer();
                   setTimeout(function () {
                       deferral.resolve([
                           { "value": 1, "text": "aranžér" },
                           { "value": 2, "text": "stavař" },
                           { "value": 3, "text": "programátor" },
                           { "value": 3, "text": "nezaměstnaný" }
                       ]);
                   }, 1000);
                   return deferral.promise;
               };

               //async basic validators - return true if specified param contains any value
               var param = new Validation.ParamValidator();
               param.ParamId = "jobs";
               param.Options = optionsFce();

               //assigned validator to property
               personValidator.RuleFor("Job",param);

Use validator to get async validation results

    this.PersonValidator = personValidator.CreateRule("Person");
    var promiseResult = this.PersonValidator.ValidateAsync(this.Data);
    promiseResult.then(function (result) {
            if (result.HasErrors){
                console.log(result.ErrorMessage);
            }
    })

Test - custom object validator with async property validation rule

     beforeEach(function(){
            //setup
            this.Data = {};
            this.PersonValidator = personValidator.CreateRule("Person");

        });


        it('fill correct data - no errors', function (done) {

            //when
            this.Data.Job = "stavař";

            //excercise
            var promiseResult = this.PersonValidator.ValidateAsync(this.Data);

            var errorInfo = this.PersonValidator.ValidationResult;
            promiseResult.then(function (response) {

                //verify
                expect(errorInfo.HasErrors).to.equal(false);

                done();

            }).done(null,done);
        });

        it('fill incorrect data - some errors', function (done) {

            //when
            this.Data.Job ="unknow job";

            //excercise
            var promiseResult = this.PersonValidator.ValidateAsync(this.Data);

            var selfValidator = this.PersonValidator;
            promiseResult.then(function (response) {

                selfValidator.ValidationResult.LogErrors();

                //verify
                expect(selfValidator.ValidationResult.HasErrors).to.equal(true);

                done();

            }).done(null,done);
        });

How to assign shared validation rule

Let`s image your object has this structure.

interface IPerson{
    IsChecked:true;
    FirstName:string;
    LastName:string;

}

To create shared validation rule

  • create AbstractValidator object
  • create validation function
  • create named validation function
  • use ValidationFor property to assign named validation function to object properties
            //create new validator for object with structure<IPerson>
             var personValidator = new Validation.AbstractValidator<IPerson>();

             //shared validation function
             var oneSpaceFce = function (args:any) {
                 args.HasError = false;
                 if (!this.Checked) return;
                 if (this.FirstName.indexOf(' ') != -1 || this.LastName.indexOf(' ') != -1) {
                     args.HasError = true;
                     args.ErrorMessage = "Full name can contain only one space.";
                     return;
                 }
             }

             //create named validation function
             var validatorFce = {Name: "OneSpaceForbidden", ValidationFce: oneSpaceFce};

             //assign validation function to properties
             personValidator.ValidationFor("FirstName", validatorFce);
             personValidator.ValidationFor("LastName", validatorFce);

Use validator to get validation results

    this.PersonValidator = personValidator.CreateRule("Person");
    var result = this.PersonValidator.Validate(this.Data);
    if (result.HasErrors){
        console.log(result.ErrorMessage);
    }

Test - custom validator object with shared validation rule

  beforeEach(function(){
            //setup
            this.Data = {};
            this.PersonValidator = personValidator.CreateRule("Person");

        });


        it('fill correct data - no errors', function () {

            //when
            this.Data.Checked = true;
            this.Data.FirstName = "John";
            this.Data.LastName = "Smith";

            //excercise
            var result = this.PersonValidator.Validate(this.Data);

            //verify
            expect(this.PersonValidator.ValidationResult.HasErrors).to.equal(false);

        });

        it('fill incorrect data - some errors', function () {

            //when
            this.Data.Checked = true;
            this.Data.FirstName = "John Junior";
            this.Data.LastName = "Smith";

            //excercise
            var result = this.PersonValidator.Validate(this.Data);

            //verify
            expect(this.PersonValidator.ValidationResult.HasErrors).to.equal(true);
        });