Reputation: 38035
I am getting the following error when trying to load a class that has validation injected into it.
key/value cannot be null or undefined. Are you trying to inject/register something that doesn't exist with DI?
I installed validation using jspm and I have verified using Chrome dev tools that the javascript for aurelia-validation is loaded (/jspm_packages/npm/[email protected]/XXX.js - there are several js files in the folder loaded in Chrome). Removing Validation
from the @inject
and 'constructor', the class loads just fine.
Here is the code...
import {Repository} from 'repository';
import {inject} from 'aurelia-framework';
import {Router} from 'aurelia-router';
import {Validation} from 'aurelia-validation';
@inject(Repository, Router, Validation)
export class Login {
constructor(rep, router, validation) {
this.rep = rep;
this.router = router;
console.log('Login');
this.login = {
EmailAddress: '',
Password: '',
Password2: ''
};
}
createAccount() {
console.log('Create Account');
this.router.navigateToRoute('verify');
}
}
What am I doing wrong? I'm new to JSPM, NPM, Aurelia, ES2016, and all the other tools in the Aurelia skeleton app, so I'm not sure where to start with this.
Upvotes: 3
Views: 1309
Reputation: 2112
The aurelia-validation plugin has been rewritten recently and the validation API has changed again with respect to the accepted answer.
It is now using 2 separate libraries aurelia-validation and aurelia-validatejs. Validators do not seem to exist anymore and have been replaced by ValidationControllers.
The new API description and some examples can be found here:
http://blog.durandal.io/2016/06/14/new-validation-alpha-is-here/
.... and a working gist can be found here:
https://gist.run/?id=381fdb1a4b0865a4c25026187db865ce
The usage can be summarized in the code below:
import {inject, NewInstance} from 'aurelia-dependency-injection';
import {ValidationController, validateTrigger} from 'aurelia-validation';
import {required, email, ValidationRules} from 'aurelia-validatejs';
@inject(NewInstance.of(ValidationController))
export class RegistrationForm {
firstName = '';
lastName = '';
email = '';
constructor(controller) {
this.controller = controller;
// the default mode is validateTrigger.blur but
// you can change it:
// controller.validateTrigger = validateTrigger.manual;
// controller.validateTrigger = validateTrigger.change;
}
submit() {
let errors = this.controller.validate();
// todo: call server...
}
reset() {
this.firstName = '';
this.lastName = '';
this.email = '';
this.controller.reset();
}
}
ValidationRules
.ensure('firstName').required()
.ensure('lastName').required()
.ensure('email').required().email()
.on(RegistrationForm);
Hope this helps.
EDIT: This has changed, apparently validatejs was a temporary solution.
This article explains how it all works now. If you used validatejs you will also have to update your ValidationRenderer. This gist shows the updated version of the renderer in use: https://gist.run/?id=1d612b3ae341c7e9c12113e1771988e7
Here is a snippet of the code coming from the blog if the link dies:
import {inject, NewInstance} from 'aurelia-framework';
import {ValidationRules, ValidationController} from "aurelia-validation";
@inject(NewInstance.of(ValidationController))
export class App {
message = '';
firstname: string = '';
lastname: string = '';
constructor(private controller: ValidationController) {
ValidationRules
.ensure((m: App) => m.lastname).displayName("Surname").required()
.ensure((m: App) => m.firstname).displayName("First name").required()
.on(this);
}
validateMe() {
this.controller
.validate()
.then(v => {
if (v.length === 0)
this.message = "All is good!";
else
this.message = "You have errors!";
})
}
}
... and the new validation renderer:
import {
ValidationRenderer,
RenderInstruction,
ValidationError
} from 'aurelia-validation';
export class BootstrapFormRenderer {
render(instruction) {
for (let { error, elements } of instruction.unrender) {
for (let element of elements) {
this.remove(element, error);
}
}
for (let { error, elements } of instruction.render) {
for (let element of elements) {
this.add(element, error);
}
}
}
add(element, error) {
const formGroup = element.closest('.form-group');
if (!formGroup) {
return;
}
// add the has-error class to the enclosing form-group div
formGroup.classList.add('has-error');
// add help-block
const message = document.createElement('span');
message.className = 'help-block validation-message';
message.textContent = error.message;
message.id = `validation-message-${error.id}`;
formGroup.appendChild(message);
}
remove(element, error) {
const formGroup = element.closest('.form-group');
if (!formGroup) {
return;
}
// remove help-block
const message = formGroup.querySelector(`#validation-message-${error.id}`);
if (message) {
formGroup.removeChild(message);
// remove the has-error class from the enclosing form-group div
if (formGroup.querySelectorAll('.help-block.validation-message').length === 0) {
formGroup.classList.remove('has-error');
}
}
}
}
Hope this helps!
Upvotes: 0
Reputation: 38035
According to this blog post, the validation code has changed.
I ended up calling jspm install aurelia-validatejs
and then changing my code to this...
import {Repository} from 'repository';
import {inject} from 'aurelia-framework';
import {Router} from 'aurelia-router';
import {Validator} from 'aurelia-validatejs';
@inject(Repository, Router)
export class Login {
constructor(rep, router) {
this.rep = rep;
this.router = router;
console.log('Login');
this.login = {
EmailAddress: '',
Password: '',
Password2: ''
};
this.validator = new Validator(this.login);
this.validator.ensure('EmailAddress')
.required();
}
createAccount() {
console.log('Create Account');
// Not sure how to actually validate yet. Before you would call
// this.validator.validate().then, but validate doesn't appear to
// return a promise anymore. Still looking into this.
}
}
Note that the import has changed as well as how you create the Validator (it is not injected).
Upvotes: 1