Tuesday, November 29, 2016

Locale-Based Message Support Added to vadacl

The latest release of my vadacl validation library for Angular 2 introduces a new feature:  locale-based error message configuration.

Prior to this release, vadacl would allow you to configure the error message for a particular validation error condition for a particular object property in either the object-based validation settings or in the component responsible for the form controls.  And if you did not declare an error message in either of those places, the validation method would return a method-specific default error message from the Messages object.  So in the following (slightly-contrived) scenario:


// app/vadacl/locale/messages-en.ts
let Messages = {
  /* DEFAULT LOCALE VALIDATOR ERROR MESSAGES */
  required: 'A value is required',
  ...
}


// app/domain/user-profile.ts
...
export class UserProfile implements Validatable {
  firstName: string = null;
  lastName: string = null;
  username: string = null;
  age: number = null;
  gender: string = null;

  validations: { [ index: string ] : PropertyValidations } = {
    firstName: {
       required: { message: 'Your first name is required.' }
    },
    lastName: {
       required: {}
    },
    username: {
       required: { message: 'Username is required.' }
    },
    age: {
       required: {}
    },
    gender: {
       required: {}
    }
  };
  ...
}

// app/forms/user-profile-form.component.ts
...
export class UserProfileForm extends Vadacl implements OnInit {
  profileForm: FormGroup;
  userProfile: UserProfile;
  ...

  ngOnInit() {
    this.userProfile = new UserProfile();

    this.profileForm = new FormGroup({
      'firstName': new FormControl(
         this.userProfile.firstName,
         this.applyRules( this.userProfile, 'firstName' )
      ),

      'lastName': new FormControl(
         this.userProfile.lastName,
         this.applyRules( this.userProfile, 'lastName', { required: { message: 'Your last name is required.' } )
      ),

      'username': new FormControl(
         this.userProfile.username,
         this.applyRules( this.userProfile, 'username', { required: { message: 'Please enter a username.' } )
      ),

      'age': new FormControl(
         this.userProfile.age,
         this.applyRules( this.userProfile, 'age' )
      ),

      'gender': new FormControl(
         this.userProfile.gender,
         this.applyRules( this.userProfile, 'gender' )
      )
    });
  }
  ...
}
...the validation error message for each UserProfile property in the UserProfileForm template that fails the required validation would be:
  • firstName: "Your first name is required."
  • lastName: "Your last name is required." (the message is provided during the FormControl instantiation)
  • username: "Please enter a username." (the component-level message overrides the object-level message)
  • age: "A value is required"
  • gender: "A value is required"

Now vadacl provides the option to configure error messages for object properties in the Messages object rather than in the validation settings in the object. Refactoring the example above to use the new feature, the code would look like:


// app/vadacl/locale/messages-en.ts
let Messages = {
  /* DEFAULT LOCALE VALIDATOR ERROR MESSAGES */
  required: 'A value is required',
  ...

  /* LOCALE-BASED DOMAIN CLASS MESSAGES */
  UserProfile: {
    firstName: {
      required: 'First name is required.'
    },
    lastName: {
      required: 'Last name is required.'
    },
    username: {
      required: 'Username is required.'
    }
  }
  ...
}

// app/domain/user-profile.ts
...
export class UserProfile implements Validatable { 
  ...
  validations: { [ index: string ] : PropertyValidations } = {
    firstName: { required: {} },
    lastName: { required: {} },
    username: { required: {} },
    age: { required: {} },
    gender: { required: {} }
  };
  ...
}

// app/forms/user-profile-form.component.ts
...
  'lastName': new FormControl(
    this.userProfile.lastName,
    this.applyRules( this.userProfile, 'lastName' )
  ),

  'username': new FormControl(
    this.userProfile.username,
    this.applyRules( this.userProfile, 'username', { required: { message: 'Please enter a username.' } )
  ),
...
...and the error messages would now be:
  • firstName: "First name is required."
  • lastName: "Last name is required."
  • username: "Please enter a username."
  • age: "A value is required"
  • gender: "A value is required"

The validation message defaults to the message in the Messages object that matches the object / property / validation method combination. If a different message is defined for that property in the object validation settings (which ordinarily you wouldn't do if you wanted to use the locale-based messages in the Messages object) or in the component when configuring the FormControl, that other message would become the message value returned when validation fails.

Configuring the validation messages in the Messages object allows you to keep all of the object-level messages in one place.  In theory, this should also give developers who need to perform internationalization the option of creating Messages objects for different languages and then altering which Messages file is imported into validation-methods.ts file as a build step prior to compiling the app.

No comments:

Post a Comment