Skip to content

Unexpected behavior with custom validator class #12423

@govorov

Description

@govorov

Hi.
I'm submitting a ...

[x] bug report

Current behavior
Here is the registration form, created with standard angular 2 form builder:

    this.form = this.formBuilder.group({
        login : [
            this.formValue.login,
            [
                Validators.required,
                Validators.minLength(loginLength.min),
                Validators.maxLength(loginLength.max),
                regexpValidator(loginPattern),
            ],
            //my custom validator class to check if login already exists
            LoginExistenceValidator,
        ],
        password : [
            this.formValue.password,
            [
                Validators.required,
                Validators.minLength(passwordLength.min),
                Validators.maxLength(passwordLength.max),
            ],
        ],
    });

As mentioned here - http://blog.thoughtram.io/angular/2016/03/14/custom-validators-in-angular-2.html#custom-validators-with-dependencies :

It turns out that a validator can also be a class as long as it implements a validate(c: FormControl) method.

Hence it is possible to inject service to acess remote data from validator.

So I created such validator:

    import { Injectable, Inject, forwardRef } from '@angular/core';
    import { Validator, FormControl }         from '@angular/forms';

    import { UsersAdapter } from 'common/adapters/users';

    @Injectable()
    export class LoginExistenceValidator implements Validator {

        private adapter;

        constructor(@Inject(forwardRef(()=>UsersAdapter)) adapter) {
            debugger
        }

        validate(control: FormControl) {
            console.log("yep i'm called");
            return function(control: FormControl){

                //validation logic

                let validator = new Promise((resolve)=>{
                    //mock random success/fail for a while
                    setTimeout(()=>{
                        let random = Math.round(Math.random());
                        let value = random ? null : { reserved: true };
                        console.log(resolve);
                        resolve(value);
                    },2000);

                });

                return validator;

            }
        }
    }

UserAdapter is a wrapper around Angular Http, which retrieves data. Now I'm not using it and every validation call should return random success/fail result.

This code throws such error in browser:

EXCEPTION: Cannot read property 'subscribe' of undefined

Error occured because Angular do not actually calls validate(), and form control passed to constructor instead of provided UserAdapter service.

When I try to use function instead of class, everything works fine.
How can I tell angular to use my validation class properly? Thanks in advance.

Expected behavior
I expect Angular to call validate() method on my custom class and use function returned by this method for form validation.

  • Angular version: 2.0.0

Thanks in advance.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions