aurelia / aurelia/validation

Rule sequences are processed differently when stored in metadata vs. on controller

Open
#482 5 comments 0 reactions 0 assignees View on GitHub
question
Dominant language
TypeScript
Stars
129
Forks
125
PR merge metrics
No merged PRs in 30d

Description

I discovered this by accident when I was answering this [SO question](https://stackoverflow.com/questions/49652607/issue-with-aurelia-validation/49703936#49703936). To quote the relevant part of my answer:

> When you call `.validate()` on a controller, it will first look for "local" rules stored via `.addObject()` and pass those to the validator via `.validateObject()`.
> The rules are processed in one pass, and the sequence behaves as it should.
>
> Then it goes through the registered bindings (added by the binding behaviors) and for each individual property it will call `.validateProperty()` on the validator *if the object is not stored on the controller*.
>
> Rather than the sequence being run once on the object, it's run once per individual property, effectively bypassing the behavior of sequences to some extent (they still apply on property level, just not on object level).

## TL;DR - 2 issues

### 1: Rule sequences don't behave as they are documented. Are the docs wrong or is the code wrong?

They are documented to simply run sequentially (rather than in parallel). What they are *really* doing is: one rule sequence evaluates to invalid -> **following rule sequences are not evaluated at all**.

### 2: Rule sequences behave differently if they are defined globally vs. on a controller. Is the global behavior correct or is the controller behavior correct?

**2.1 Globally via the fluent terminator `.on(obj)`**, they are evaluated **per property**. Meaning if you have a single rule for each property in a sequence, each rule will be evaluated and result in a validation message since non-matching sequences are skipped.

**2.1 On the controller via `.addObject(obj, rules)`**, they are evaluated **per object**. So the exactly same rules as above will result in only one property being evaluated, rather than all of them.

## Addendum

If the behavior as described in .1 is indended, then .2.2 more or less represents the way it *should* be: one rule evaluates to invalid, no further rules are processed. If .1 is **not** intended, then .2.1 is more like how it should be (though not entirely)

### This is not an urgent issue, but it's a very subtle bug/inconsistency that should be addressed at some point.

A decision needs to be made on what the intended behavior is, and then I could potentially help with a PR to make the code behave that way consistently in the different scenarios.

Contributor guide

Open the contributing guide

Research direction

Start by tracing controller .validate(), validator .validateObject(), and .validateProperty(), comparing rules registered through .on(obj) with those passed to .addObject(obj, rules). The issue requires deciding the intended sequence semantics before changing behavior. Done means the decision is documented and both registration paths consistently follow it.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.