Search code examples
validationaurelia

Aurelia validatejs not working when bind on a object


I was playing around with aurelia-validatejs and was able to validate simple fields on a page. On the same page, I tried initializing a object and bind validation to that object and it stops working:

user_data:IUserData = {
    Login:"",
    Id         : null,
    UserProfile: {
        UserId: null
    },
    Permissions: null
};
constructor(){
    this.reporter = ValidationEngine.getValidationReporter(this.user_data);

    // if I just use this and not user_data object,
    // it works and error message is displayed in UI

    this.validator = new Validator(this.user_data)
        // when I use this.user_data (user_data object), it does validate 
        // and I can see validation result on console, but it's not shown in UI

        .ensure('Login').required().length({minimum: 3, maximum:10});
        this.observer = this.reporter.subscribe(result => {
            console.info(result);
        });
}

Someone mentioned that validatejs looks for a label, and I do have it, it worked when I initialize on this object but as soon as I want to validate on this.user_data property, it just doesn't display in UI, but I can see it on console.

<form action="" submit.delegate="createUser()">
    <div class="input-group ${user_data.Login | loginClass}">
        <label></label>
        <input placeholder="Login" type="text" class="form-control"
            keyup.delegate="validate()"  value.bind="user_data.Login & validate">
    </div>
</form>

This doesn't work, but if I clear user_data like:

    user_data:IUserData = {
        Login:"",
        Id         : null,
        UserProfile: {
            UserId: null
        },
        Permissions: null
    };
constructor(){
        this.reporter = ValidationEngine.getValidationReporter(this);

        //if I just use this and not user_data object,
        //it works and error message is displayed in UI

        this.validator = new Validator(this)
            .ensure('Login').required().length({minimum: 3, maximum:10});
        this.observer = this.reporter.subscribe(result => {
            console.info(result);
        });
}

and

<form action="" submit.delegate="createUser()">
    <div class="input-group ${user_data.Login | loginClass}">
        <label></label>
        <input placeholder="Login" type="text" class="form-control"
            keyup.delegate="validate()"  value.bind="Login & validate">
    </div>
</form>

This works and is displayed in UI. I searched a little bit on Stack Overflow and got few results: similar. (My problem is similar. I have error messages on UI if I don't use it on a object but when I try to use it on an object, it logs on console but it doesn't display in UI.)

I also found this but it wasn't of much help.

I found one more which wasn't of much help either.


Solution

  • So I dug around a little bit and asked developers in Gitter. As it turns out, it's a bug in validatejs plugin.

    Recent changes were made to make something available on all classes, and when that change was done, validatejs looks for validationError Reporter on same model even if we provide different model.

    A small hacky workaround is to have

    this.__validationReporter__ = ValidationEngine
        .getValidationReporter(this.user_data);
    

    Instead of:

    this.reporter = ValidationEngine.getValidationReporter(this.user_data);
    

    I have reported this issue and will update once they come up with something.

    For now I'm gonna use

    this.__validationReporter__ = ValidationEngine
        .getValidationReporter(this.user_data);
    

    Or one other workaround is to downgrade to 0.3.x which is not very recommended as there might have been some important changes.