Angular Custom Async Validator保持挂起状态

时间:2017-10-17 18:15:59

标签: angular validation asynchronous

我有一个自定义验证器,用于验证用户的电子邮件是否唯一。

我在stackoverflow和互联网上搜索了相关主题,但没有帮助

当我在表单中发送输入(发送请求)时,请求将保持挂起状态并且不会解析。

我已经测试了postman的后端,它按预期工作,问题出在客户端或有角度的一面。

验证功能如下:

emailUniqueValidator (control: AbstractControl): Promise<{[key: string]: any}> | Observable<{[key: string]: any}> {
    return new Promise((resolve, reject) => {
      this.userService.checkEmailUnique(control.value).subscribe((response: Response) => {
        const body = response.json();
        if (body.found === false) {
          resolve(null); // email is unique
        } else {
          reject({emailUniqueValidator: true}); // email is not unique
        }
      });
    });
  }

当我更改表单控件的值时,将显示挂起的类,但它会永远存在而不是被解析。

我的电子邮件表单控件如下:

'email': new FormControl('', [
        Validators.required,
        Validators.email
      ], this.emailUniqueValidator.bind(this)
),

我的用户服务如下:

checkEmailUnique (email: string): Observable<Response> {
    return this.http.post('http://localhost:3000/user/email', {email}, { withCredentials: true });
  }

为什么验证器没有及时解决并永远保持待定状态?

修改

以下代码从服务中获取价值就好了,我通过将响应记录到控制台来检查它。

如果数据库中没有电子邮件,那么它就会被解决得很好,但是如果电子邮件已经存在,则会发出错误并且状态仍然未决。

return new Promise((resolve, reject) => {
      this.userService.checkEmailUnique(control.value).subscribe((response: Response) => {
        console.log(response);
        response.json().found ? reject({emailUniqueValidator: true}) : resolve(null);
      }, (error: any) => reject({emailUniqueValidator: true}));
});

4 个答案:

答案 0 :(得分:3)

观察者永远不会完成。

尝试在最后添加.first()

emailUniqueValidator (control: AbstractControl): Observable<{[key: string]: any}> {
    return this.userService.checkEmailUnique(control.value)
               .map(r => r.json())
               .map(r => (r.found) ? {emailUniqueValidator: true} : null)
               .first();
 }

答案 1 :(得分:1)

我有同样的问题。我删除了changeDetection: ChangeDetectionStrategy.OnPush,它起作用了。一个示例is here

答案 2 :(得分:1)

确保您的“状态代码来自”服务在任何情况下均为200

var user = _appRepository.GetUserByUserName(username);
if (user != null)

    return Ok(user );
}
return Ok();

这是来自asp.net核心api。当用户不可用时,发送空的Ok()。如果角度捕获404或400,则始终显示未决。

export function uniqueUsernameValidator(userService: UserService): AsyncValidatorFn {
  return (c: AbstractControl): Observable<{ [key: string]: any } | null> => {
    return userService.getUserByUsername(c.value).pipe(
      map(users => {
        console.log(users)
        if (users) {
          return { 'unique': true};
        }else {
          return null
        }
      })
    )
  };
}

答案 3 :(得分:0)

为什么你要完成承诺一个可观察到的头痛的承诺?试试这样:

emailUniqueValidator (control: AbstractControl): Observable<{[key: string]: any}> {
    return this.userService.checkEmailUnique(control.value)
               .map(r => r.json())
               .map(r => (r.found) ? {emailUniqueValidator: true} : null);
 }