Angular 11异步验证器触发真实响应的无限循环请求
Posted
技术标签:
【中文标题】Angular 11异步验证器触发真实响应的无限循环请求【英文标题】:Angular 11 async validator triggering endless loop of requests on true response 【发布时间】:2021-03-01 06:43:34 【问题描述】:因此,我正在创建一个带有异步现有用户验证的简单注册表单,它执行对我的 API 的 http 请求,该请求为现有用户返回一个布尔值。
组件:
import Component, OnInit from '@angular/core';
import FormBuilder, FormGroup, Validators from '@angular/forms';
import UserTakenValidatorService from '../../services/user-taken.validator.service';
@Component(
selector: 'app-signup',
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.less'],
)
export class SignupComponent implements OnInit
public signupForm: FormGroup;
public hide = true;
constructor(
private formBuilder: FormBuilder,
private checkUserTaken: UserTakenValidatorService,
)
ngOnInit(): void
this.signupForm = this.formBuilder.group(
email: ['', [Validators.required, Validators.email]],
fullName: ['', [Validators.required, Validators.maxLength(40)]],
userName: [
'',
[Validators.required, Validators.maxLength(20)],
this.checkUserTaken.checkUserNameTaken(),
],
password: ['', [Validators.required, Validators.minLength(8), Validators.maxLength(20)]],
);
signup()
console.log(this.signupForm.controls.userName.errors);
这是验证器:
import HttpClient from '@angular/common/http';
import Injectable from '@angular/core';
import AbstractControl from '@angular/forms';
import map from 'rxjs/operators';
const API_URL = 'http://localhost:3000';
@Injectable( providedIn: 'root' )
export class UserTakenValidatorService
constructor(private http: HttpClient)
checkUserNameTaken()
return (control: AbstractControl) =>
return this.verifyUsername(control.value)
.pipe(map((isTaken) => (isTaken ? userNameTaken: true : null)))
;
private verifyUsername(userName: string)
return this.http.get<boolean>(`$API_URL/user/exists/$userName`);
当输入现有用户(即来自 API 的 true 响应)时,这会触发无限循环的请求,这些用户也不会向 signupForm.controls.userName.errors
添加错误,并且会在第一个错误时停止回应。
P.S.:依赖是 @angular/core/forms/common 11.0.0
和 rxjs 6.6.0
【问题讨论】:
【参考方案1】:Angular HttpClient 默认需要一个 JSON。您的回复似乎只包含一个字符串,它代表一个布尔值。
请尝试以下方法
private verifyUsername(userName: string)
return this.http.get<string>(`$API_URL/user/exists/$userName`, responseType: 'text' ).pipe(
map(stringBoolean => stringBoolean === 'true'),
);
【讨论】:
我在更彻底的分析中删除了我之前的评论原因,即使它抛出了一个奇怪的“没有重载匹配这个调用”(在 Angular 文档中作为 Overload #3),它确实编译返回一个string
不断触发循环。更改为 responseType: 'json'
(重载#15)似乎有效,但响应类型为boolean
,因此在地图条件下始终返回false
;试图删除它,带回循环。以上是关于Angular 11异步验证器触发真实响应的无限循环请求的主要内容,如果未能解决你的问题,请参考以下文章