
Question:
I'm trying to validate an object property of an Aurelia ViewModel.
ViewModel
@autoinject
class AddUserForm {
user: User;
controller: ValidationController;
constructor(controllerFactory: ValidationControllerFactory) {
this.controller = controllerFactory.createForCurrentScope();
}
validate() {
this.controller.validate.then(res => {
console.log(res.valid);
})
}
}
ValidationRules
.ensure((u: User) => u.id).displayName('User').required()
.on(AddUserForm)
ViewModel -> View
<template>
<form click.trigger="validate()">
<input type="text" value.bind="user.id & validate" />
</form>
</template>
User
class User {
id: string
}
The issue I'm having is that the validator is not picking up the nested user object. I'm I missing something to get this working? I read the <a href="http://aurelia.io/hub.html#/doc/article/aurelia/validation/latest/validation-basics/6" rel="nofollow">docs</a> and it seems like this should work. I'm using version ^1.0.0
of the plugin.
The problem is in your ValidationRules:
ValidationRules
.ensure((u: User) => u.id).displayName('User').required()
.on(AddUserForm)
needs to be
ValidationRules
.ensure((u: User) => u.id).displayName('User').required()
.on(User)
Then to get the controller to run this rule you either need to include "& validate" somewhere in your value.bind <em>for that property</em>, like this:
<input value.bind="user.id & validate" />
or before you call controller.validate(), add the entire object to the controller like this:
this.controller.addObject(this.user);
I use .addObject <em>all the time</em> because it causes validation to run on properties that aren't included in your markup, and I find I prefer that.
Answer2:This caused an error when I tried it:
validate() {
this.controller.validate(res => {
console.log(res.valid);
})
}
.validate() expects a ValidateInstruction, in your example you're giving (res: any) => void. I would try changing to this instead:
this.controller.validate().then(res => {
console.log(res.valid);
});
Leaving .validate() undefined will cause it to validate all objects and bindings, and .then() will execute after that validation has completed. This worked for me when I tried it in my test project.
If I misunderstood your question and this alone does not solve it however, you could also try assigning the User
objects id to a property in AddUserForm
like this:
public userId = this.user.id;
And changing your ValidationRules and view accordingly:
<strong>ViewModel</strong>
ValidationRules
.ensure((u: AddUserForm) => u.userId)
.displayName("User")
.required()
.on(this);
<strong>View</strong>
<template>
<form click.delegate="validate()">
<input type="text" value.bind="userId & validate" />
</form>
</template>