简体   繁体   English

角2-自定义表单验证程序不起作用-无法读取null的属性“值”

[英]Angular 2 - Custom Form Validator not working - Cannot read property 'value' of null

I am trying to create a custom form validator, but I keep getting this error Cannot read property 'value' of null. 我正在尝试创建一个自定义表单验证器,但我不断收到此错误。无法读取null的属性“值”。 I have been really struggling with is issue for days now and here is my FormGroup: 我已经为问题困扰了好几天了,这是我的FormGroup:

this.step1Form = this.fb.group({
                username: new FormControl('', {
                        validators: [Validators.required,
                        Validators.minLength(4),
                        this.checkUsername.bind(this)],
                }),
                email: new FormControl('', {
                        validators: [Validators.required,
                        Validators.pattern("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")],
                }),
                password: new FormControl('', {
                        validators: [Validators.required,
                        Validators.minLength(8)],
                }),
                repeat: new FormControl('', {
                        validators: [Validators.required,
                        Validators.minLength(8)],
                }),
                });

Here is my checkUsername method 这是我的checkUsername方法

checkUsername(g: FormGroup) {
                return this.dataService.checkUsername(g.get('username').value).pipe(map(data => {
                        return typeof data["error"] != 'undefined' ? null : {'taken': true};
                }));
        }

and here is the checkUsername method in this.dataService 这是this.dataService中的checkUsername方法

checkUsername(username):Observable<any> {
            return this.http.get(globals.baseUrl+'/user/' + username, {headers:this.utilService.getHeadersJson()}).map(this.utilService.map);
        }

And I get the error: 我得到了错误:

Cannot read property 'value' of null 无法读取null的属性“值”

on this line 在这条线上

return this.dataService.checkUsername(g.get('username').value).pipe(map(data => {

What am I doing wrong? 我究竟做错了什么? I have tried without the pipe like so 我试过没有这样的管道

checkUsername(g: FormGroup) {
    return this.dataService.checkUsername(g.get('username').value).subscribe(data => {
            return typeof data["error"] != 'undefined' ? null : {'taken': true};
    });
}

but that didnt work, I have also tried my validator in different positions like so: 但这没有用,我也尝试过在不同位置进行验证器,如下所示:

this.step1Form = this.fb.group({
        username: new FormControl('', {
                validators: [Validators.required,
                Validators.minLength(4)],
        }),
        email: new FormControl('', {
                validators: [Validators.required,
                Validators.pattern("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")],
        }),
        password: new FormControl('', {
                validators: [Validators.required,
                Validators.minLength(8)],
        }),
        repeat: new FormControl('', {
                validators: [Validators.required,
                Validators.minLength(8)],
        }),
        }, { validator: this.checkUsername.bind(this)});

Also didnt work. 也没有工作。

PLEASE HELP! 请帮忙!

I have also tried this: 我也尝试过这个:

username: new FormControl('', {
                        validators: [Validators.required,
                        Validators.minLength(4)],
                        asyncValidator: [this.checkUsername.bind(this)],

 }),

got this error: 得到这个错误:

Argument of type '{ validators: ValidatorFn[]; 类型'{验证程序:ValidatorFn []; asyncValidator: any[]; asyncValidator:any []; }' is not assignable to parameter of type 'ValidatorFn | }'不能分配给'ValidatorFn |类型的参数。 AbstractControlOptions | AbstractControlOptions | ValidatorFn[]'. ValidatorFn []'。 Object literal may only specify known properties, and 'asyncValidator' does not exist in type 'ValidatorFn | 对象文字只能指定已知属性,并且'ValidatorFn |类型中不存在'asyncValidator'。 AbstractControlOptions | AbstractControlOptions | ValidatorFn[]'. ValidatorFn []'。

Angular reactive forms call the validators immediately and often. 角反应形式立即并经常调用验证器。 The cross-field validator on your form group will begin to validate as each child control is instantiated by the framework. 在框架实例化每个子控件时,表单组中的跨域验证器将开始进行验证。

To prevent it from throwing premature validation errors, you'll probably want to ensure that the control in question has been instantiated, like so: 为了防止它引发过早的验证错误,您可能需要确保所涉及的控件已实例化,如下所示:

checkUsername(g: FormGroup) {
    if (!g || !g.get('username')) {
        return null;
    }
    return this.dataService.checkUsername(g.get('username').value).subscribe(data => {
        return typeof data["error"] != 'undefined' ? null : {'taken': true};
    });
}

Your 2nd attempt seems like a better direction to go, however, because it's an asynchronous validator for the 'username' control, but you have a typo in the asyncValidators property (missing the 's'). 但是,您的第二次尝试似乎是一个更好的方向,因为它是“用户名”控件的异步验证器,但是asyncValidators属性中有一个错字(缺少“ s”)。 You also likely don't need to .bind(this) if you're not referencing "this" in the function. 如果您未在函数中引用“ this”,则也可能不需要.bind(this)。

username: new FormControl('', {
  validators: [Validators.required, Validators.minLength(4)],
  asyncValidators: [this.checkUsername]
})

Then your validator is just handling a single form control instead of the whole group, something like this: 然后,您的验证程序将只处理单个表单控件而不是整个组,如下所示:

checkUsername(c: FormControl) {
    if (!c) { return null; }
    return this.dataService.checkUsername(c.value).subscribe(data => {
        return typeof data["error"] != 'undefined' ? null : {'taken': true};
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM