validation: Expression 'command.InternalNotes&validate' is not compatible with the validate binding-behavior.
Hi,
I’m new to this library, using the latest version (both of aurelia framework & validation). My configuration is skeleton navigation typescript with webpack.
My class is configured as following:
import { autoinject, newInstance } from 'aurelia-framework';
import { OrderService } from '../order-service';
import { Router } from 'aurelia-router';
import { ValidationController, ValidationRules } from 'aurelia-validation';
import { BootstrapFormRenderer } from '../../resources/validation/bootstrap-form-renderer';
@autoinject
export class OrderSetInternalNotes {
heading: string = 'Set internal notes';
command: any = null;
constructor(private orderService: OrderService,
private router: Router,
@newInstance(ValidationController) private validationController: ValidationController) {
this.validationController.addRenderer(new BootstrapFormRenderer());
}
activate(params) {
this.orderService.getSetInternalNotes(params.id, params.timestamp).then(getSetInternalNotesResponse => {
if (!getSetInternalNotesResponse.Meta.Success) {
this.cancel();
}
this.command = getSetInternalNotesResponse.Results[0];
ValidationRules
.ensure('InternalNotes').required().maxLength(5)
.on(this.command);
});
}
async execute() {
let errors = await this.validationController.validate();
if (errors.length > 0){
return;
}
let getSetInternalNotesResponse = await this.orderService.setInternalNotes(this.command);
if (!getSetInternalNotesResponse.Meta.Success) {
return;
}
this.close();
}
cancel() {
this.close();
}
private close() {
this.router.navigateToRoute('orderList');
}
}
the object “command” is gathered from the server and then I’d like to attach the validation when ready.
here is the html
<template>
<section class="au-animate">
<h2>${heading}</h2>
<form role="form" submit.delegate="execute()">
<div class="form-group">
<label for="internalNotes">Intenal notes</label>
<textarea class="form-control"
rows="12"
value.bind="command.InternalNotes & validate"
id="internalNotes"></textarea>
</div>
<button type="submit" class="btn btn-primary">Ok</button>
<button click.delegate="cancel()" class="btn btn-default">Cancel</button>
</form>
</section>
</template>
Am I doing something wrong?
Thanks for any advice! Enrico
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 31 (3 by maintainers)
Commits related to this issue
- chore(all): update aurelia-binding dependency - Fixes #490 - Fixes #350 — committed to fkleuver/validation by fkleuver 6 years ago
Yep, was able to reproduce this. It goes wrong here:
An expression of type
BindingBehavior
comes in butexpression instanceof BindingBehavior
evaluates to false.It appears that 1.7.1 is stored in the lockfile as a redirect from
^1.0.0
and 2.0.0 is stored as a separate entry. The Aurelia libraries depending onaurelia-binding
all get their own reference to 1.7.1.So you get this effect:
aurelia-binding@^2.0.0
aurelia-binding@^1.7.1
aurelia-binding@^1.7.1
aurelia-templating-binding
loads its own version to parse the expressions,aurelia-validation
also loads its own version to compare the constructors. They’re both 1.7.1 (2.0.0 isn’t even loaded) but different instances, so the constructor functions don’t match up.1.7.1 being loaded doesn’t really surprise me though - that’s semantic versioning doing its job. I guess the dependency on
aurelia-binding
needs to be changed to “^1.0.0 | ^2.0.0”.What does baffle me is that each library loads its own unique instance, even of the same version. At the very least should the same 1.7.1 instance be reused so this sort of thing doesn’t happen. I’d argue that’s a webpack issue, but I’m not entirely sure.
In any case, mismatches in versions like this will always cause problems when using
instanceof
. The mismatch really has to be avoided.@bigopon @EisenbergEffect
@fkleuver bringing this to your attention
I am not sure if this is helpful but I ran a working version next to a failing version and I see some differences in what ValidateController passes to getPropertyInfo.
Working version: expression.constructor.name – returns “AccessMember”
Non-working version: expression.constructor.name – returns “BindingBehavior” I can see expression.expression.constructor.name is “AccessMember”
As an experiment I changed getPropertyInfo in the failing version look for expression.expression and at a high level validation seems to work. It could probably have used expression.expression instanceof but this was just a proof of concept. Of course, I have don’t really know how it is supposed to be working but maybe this helps figure out the root cause of this error.
export function getPropertyInfo(expression, source) { var originalExpression = expression; while (expression instanceof BindingBehavior || expression instanceof ValueConverter) { expression = expression.expression; } var object; var propertyName; if (expression instanceof AccessScope) { object = getContextFor(expression.name, source, expression.ancestor); propertyName = expression.name; } else if (expression.expression.constructor.name === “AccessScope”) { object = getContextFor(expression.expression.name, source, expression.expression.ancestor); propertyName = expression.expression.name; } else if (expression instanceof AccessMember) { object = getObject(originalExpression, expression.object, source); propertyName = expression.name; } else if (expression.expression.constructor.name === “AccessMember”) { object = getObject(originalExpression.expression, expression.expression.object, source); propertyName = expression.expression.name; } else if (expression instanceof AccessKeyed) { object = getObject(originalExpression, expression.object, source); propertyName = expression.key.evaluate(source); } else if (expression.expression.constructor.name === “AccessKeyed”) { object = getObject(originalExpression.expression, expression.expression.object, source); propertyName = expression.expression.key.evaluate(source); } else { throw new Error(“Expression '” + originalExpression + “’ is not compatible with the validate binding-behavior.”); } if (object === null || object === undefined) { return null; } return { object: object, propertyName: propertyName }; }
I am also running into this issue after upgrading to aurelia-binding 2.0.0 while upgrading to webpack 4. I downgraded to 1.7.1, deleted my node_modules folder and package-lock.json and reran npm install. I am still getting the same error. Using webpack 4.8.3, npm 6.0.1 various version of aurelia-binding. When I have a little more time, I will bring up a working version and see what is different in the way it checks to see if expression as an instance of AccessMember.
I think I’ve just found the problem: an out-of-date reference to aurelia-binding. In fact I didn’t have an explicit reference to it in package.json.
I’ve just explicitly installed aurelia-binding 1.7.1 and now aurelia-validation 1.1.3 is working for me.
@avrahamcool Does this work for you too?
I’ve just encountered this issue too with aurelia-validation 1.1.3. I’ve just upgraded to Webpack 4, and along with that updated all my other aurelia dependencies. So it’s a little tricky to tell exactly what is the problem.
I tried uninstalling and reinstalling aurelia-validation 1.1.3 but that didn’t help. Neither did trashing my node_modules directory and doing npm install again.
In the end I had to revert to aurelia-validation 1.1.2 which works fine.
I don’t think I’m doing anything unusual with the validation. My setup code is
@enrico-padovani I would suggest you to clear node_modules first and re-install
@enrico-padovani so, I have fixed this issue, this worked for me: