Angular 2 - не работает пользовательский валидатор форм - невозможно прочитать свойство 'value' из null - PullRequest
1 голос
/ 22 мая 2019

Я пытаюсь создать собственный валидатор формы, но получаю эту ошибку. Не удается прочитать свойство 'значение', равное нулю. Я действительно много дней боролся с этой проблемой, и вот моя 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)],
                }),
                });

Вот мой метод checkUsername

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

и вот метод checkUsername в this.dataService

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

И я получаю ошибку:

Невозможно прочитать свойство 'value' из null

в этой строке

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

Что я делаю не так? Я пробовал без трубы вот так

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

но это не сработало, я также пробовал свой валидатор на разных позициях, например:

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)});

Также не работает.

ПОЖАЛУЙСТА, ПОМОГИТЕ!

Я также пробовал это:

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

 }),

получил эту ошибку:

Аргумент типа '{validators: ValidatorFn []; asyncValidator: любой []; } 'нельзя назначить параметру типа' ValidatorFn | AbstractControlOptions | ValidatorFn []. Объектный литерал может только указать известные свойства, а asyncValidator не существует в типе 'ValidatorFn | AbstractControlOptions | ValidatorFn [].

1 Ответ

0 голосов
/ 22 мая 2019

Угловые реактивные формы вызывают валидаторы сразу и часто.Валидатор кросс-полей в вашей группе форм начнет проверяться, когда каждый дочерний элемент управления создается платформой.

Чтобы предотвратить появление ошибок преждевременной проверки, вы, вероятно, захотите убедиться, что соответствующий элемент управлениябыл создан, например, так:

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};
    });
}

Ваша вторая попытка кажется лучшим направлением, потому что это асинхронный валидатор для элемента управления 'username', но у вас есть опечатка в свойстве asyncValidators(пропуская 's').Вам также, вероятно, не понадобится .bind (this), если вы не ссылаетесь на "this" в функции.

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

Тогда ваш валидатор просто обрабатывает один элемент управления формы вместо всей группыпримерно так:

checkUsername(c: FormControl) {
    if (!c) { return null; }
    return this.dataService.checkUsername(c.value).subscribe(data => {
        return typeof data["error"] != 'undefined' ? null : {'taken': true};
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...