ValidationRules ensureObject().satisfies() not working


#1

Hi,

I’ve just started to try using .ensureObject when validating objects. I rarely have the need, but very occasionally I want to do this:

ValidationRules
  .ensure(a => a.firstName).required()
  .ensure(a => a.lastName).required()
  .ensure(a => a.email).required().email()
  .ensureObject().satisfies(a => {
    return /* some complex condition of the object */;
  })
  .on(...);

I understand that the rule won’t get called on any property change, because ensureObject is not tied to a particular property. But I cannot get the rule to be called ever. this.controller.validate() should run all rules (including ensureObject rules), but it doesn’t.

I’ve created a gist here showing the problem. Enter all form fields and click submit. The form should fail (because ensureObject().satisfies() always returns false) and yet validation passes.

Any ideas? Thanks!


#2

Hi. Is here any solution? Currently I’m facing the same issue.


#3

Last I checked there wasn’t, but I haven’t looked at updated versions in a while. The way I got around it was to use normal property validation on a property that didn’t need validation and wasn’t displayed on the UI, and then I used the object passed to that function to get the same behaviour.

I hope that makes sense, I’m typing from my mobile. Let me know if you want an example!


#4

ok. That’s quite sad that this doesn’t work as described in documentation. I don’t want to implement any workarounds for validation :confused:

In my case I have an object including a person object two times (following just a rough example knowing that this isn’t the best one):

{
    house: {
        person:  {
            id = 1
        }
    },
    person: {
        id=1
    }
}

How can I know assure, that the person-id of the house-object is the same as the person-id of the root person-object?

“ensureObject.satisfies” seems not to work as stated in this issue-post.


#5

Not sure of the reasons behind using .ensureObject.
But have you tried just doing something like this (from the documentation - https://aurelia.io/docs/plugins/validation#entity-validation):

  ValidationRules
      .ensureObject()
        .satisfies(obj => obj.length * obj.width * obj.height <= 50)
          .withMessage('Volume cannot be greater than 50 cubic centemeters.')
      .on(Shipment);
  

I have similar working fine. Note - from the docs:

satisfies((value: any, object?: any) => boolean|Promise)validates the supplied function returnstrueor aPromisethat resolves totrue` . The function will be invoked with two arguments:

  • the property’s current value.
  • the object the property belongs to.

So you can do: .satisfies((val, obj) => /* some complex condition of the object */


#6

According to the documentation (https://aurelia.io/docs/plugins/validation#entity-validation):

The controller can validate whole entities even if some of the properties aren’t used in data bindings. Opt in to this “entity” style validation using the controller’s addObject(object, rules?) method. Calling addObject will add the specified object to the set of objects the controller should validate when its validate method is called.

So, to make your gist working you need to add this code to some lifecycle hook (i.e. created()) of your registration-form component:

created() {
    this.controller.addObject(this);
    ValidationRules
      .ensure(a => a.firstName).required()
      .ensure(a => a.lastName).required()
      .ensure(a => a.email).required().email()
      .ensureObject().satisfies(a => {
           console.log("ensure object!!", a);
           return false;
       })
      .on(this);
}