One of our testers finally got a chance to have a look at our Aurelia App, which is extremely rare and she found an issue where validation would not apply under certain conditions.
After a little bit of investigating, the conditions turned out to be editing ... sigh
This is the code:
import { ValidationController, validateTrigger, ValidationRules, ValidationError } from 'aurelia-validation';
import { BootstrapFormRenderer } from '../../validation/bootstrapFormRenderer'
import { stuff here } from ...
import { inject, NewInstance, computedFrom, BindingEngine } from 'aurelia-framework';
import { Router } from 'aurelia-router';
import { AuthService } from 'aurelia-authentication'
@inject(BindingEngine, NewInstance.of(ValidationController), Router, AuthService)
export class AddEditUser {
private User this.user;
constructor(bindingEngine: BindingEngine, validationController: ValidationController, router: Router, authService: AuthService) {
this.bindingEngine = bindingEngine;
this.router = router;
this.authService = authService;
this.validationController = validationController;
this.validationController.validateTrigger = validateTrigger.changeOrBlur;
this.validationController.addRenderer(new BootstrapFormRenderer());
this.user = new User();
}
activate(params, navigationInstruction) {
this.editMode = Object.keys(params).length > 0;
if (this.editMode) {
this.service.find(params.id).then(user => {
this.user = new User(user.Id,
user.FirstName,
user.MiddleName,
user.LastName,
user.Email,
user.UserName,
user.JobRole,
user.PhoneNumber,
user.UserRole,
user.ContactPreference,
null,
null,
user.Status);
});
}
}
bind() {
ValidationRules
.ensure("userName").required().maxLength(256).matches(/^[a-z0-9@\.\-\_]+$/i).withMessage("User Name can be up to 256 characters long. Only alphanumeric characters and . _ - @ are allowed.")
.ensure("firstName").required().maxLength(64).matches(/^([a-zA-Z\'\-\s])+$/i).withMessage("First Name can be up to 64 characters long. Only letters, apostrophes, hyphens and spaces are allowed.")
.ensure("middleName").maxLength(64).matches(/^([a-zA-Z\'\-\s])+$/i).withMessage("Middle Name can be up to 64 characters long. Only letters, apostrophes, hyphens and spaces are allowed.")
.ensure("lastName").required().maxLength(64).matches(/^([a-zA-Z\'\-\s])+$/i).withMessage("Last Name can be up to 64 characters long. Only letters, apostrophes, hyphens and spaces are allowed.")
.ensure("email").email().withMessage("Provide a valid Email.").maxLength(256)
.ensure("email").required().when((user: User) => user.contactPreference === ContactPreferenceType.Email).withMessage("Email is required when it's your contact preference")
.ensure("phoneNumber").minLength(10).maxLength(12).matches(/^\d+$/).withMessage("Provide a valid Phone number. Only numbers allowed")
.ensure("phoneNumber").required().when((user: User) => user.contactPreference === ContactPreferenceType.SMS).withMessage("Phone number is required when it's your ontact preference")
.ensure("status").required()
.ensure("role").required()
.on(this.user);
}
public saveUser() {
this.validationController.validate()
.then((errors: ValidationError[]) => {
if (errors.length === 0) {
this.service.update(this.user.userName, this.user.firstName, this.user.middleName, this.user.lastName,
this.user.email, this.user.phoneNumber, this.user.contactPreference, this.selectedTeam.id, this.selectedOrganization.id,
this.user.jobRole, this.user.status, this.user.role).then(result => {
this.userUpdated = true;
this.navigateBack();
}).catch(error => {
console.log(error);
this.failedToUpdateUser = true;
});
}
});
}
public addUser() {
this.validationController.validate()
.then((errors: ValidationError[]) => {
if (errors.length === 0) {
this.service.register(this.user.userName, this.user.firstName, this.user.middleName, this.user.lastName,
this.user.email, this.user.phoneNumber, this.user.contactPreference, this.selectedTeam.id, this.selectedOrganization.id,
this.user.jobRole, this.user.status, this.user.role).then(result => {
this.userAdded = true;
this.navigateBack();
}).catch(error => {
console.log(error);
this.failedToAddUser = true;
});
}
});
}
public submit() {
if (this.editMode) {
return this.saveUser();
}
return this.addUser();
}
}
And this is what I did to get it working, namely add the rules to the object after the object (user) was created.
activate(params, navigationInstruction) {
this.editMode = Object.keys(params).length > 0;
if (this.editMode) {
this.service.find(params.id).then(user => {
this.user = new User(user.Id,
user.FirstName,
user.MiddleName,
user.LastName,
user.Email,
user.UserName,
user.JobRole,
user.PhoneNumber,
user.UserRole,
user.ContactPreference,
null,
null,
user.Status);
this.bind()
});
}
}
I tried this too but it made no difference, on the saveUser method.
this.validationController.addObject(this.user);