基于角度模型的形式的异步验证不能将null转换为对象

时间:2018-03-13 16:40:22

标签: angular validation typescript

我试图在角度基础上对基于模型的表单进行异步验证。为简单起见,我删除了表单的所有其他字段。在实际示例中,还有更多字段。

public_data

buildForm(): void { this.registerForm = this.fb.group({ 'username': [this.user.username, [Validators.required, Validators.minLength(4)], [this.validateUsernameUnique.bind(this)]] }); this.registerForm.valueChanges .subscribe(data => this.onValueChanged(data)); this.onValueChanged(); // set validation messages now } 方法应调用服务并远程检查用户名是否已存在并返回true或false。该服务正常运行,其结果按预期显示在控制台上。

validateUsernameUnique()

我尝试跳过此验证,直到值为> = 4,因为我希望validateUsernameUnique(control: AbstractControl) { clearTimeout(this.usernameCheckTimeout); return new Promise((resolve) => { this.usernameCheckTimeout = setTimeout(() => { if (control.value.length >= 4) { this.userService.doesUsernameExist(control.value) .then(res => { if (!res) { resolve(null); } else { resolve({nameTaken: true}); } }); } else { resolve(null); } }, 1000); }); } - 验证在此之前显示。

验证消息的定义如下:

minLength(4)

minLength() - 检查按预期在开头工作,formErrors = { 'username': '' }; validationMessages = { 'username': { 'required': 'username is required', 'minlength': 'username must be at least 4 characters long', 'nameTaken': 'username does already exist' } }; 也显示在表单上。但当我达到4个字符时,我在控制台中出现异常:

username must be at least 4 characters long

发生错误后,不再显示验证消息,minLength-Validation也不再有效。

stackTrack报告TypeError: can't convert null to object Stack trace: UserRegisterComponent.prototype.onValueChanged@webpack-internal:///./src/app/user/user-register/user-register.component.ts:111:39 UserRegisterComponent.prototype.buildForm/<@webpack-internal:///./src/app/user/user-register/user-register.component.ts:63:49 中的问题,此方法如下所示:

onValueChanged():111
  • 如何让同步和异步验证并行工作?我在同一个组件中使用async-Validation-Method获取方法,该方法也来自SO。

  • 如何让onValueChanged(data?: any) { if (!this.registerForm) { return; } const form = this.registerForm; for (const field of Object.keys(this.formErrors)) { // clear previous error message (if any) this.formErrors[field] = ''; const control = form.get(field); if (control && control.dirty && !control.valid) { const messages = this.validationMessages[field]; for (const key of Object.keys(control.errors)) { this.formErrors[field] += messages[key] + ' '; } } } } - errorMessage出现在表单上?验证中的nameTaken承诺是错误的方法吗?

任何意见都表示赞赏。不知道我究竟如何调试电流行为以了解问题所在。

1 个答案:

答案 0 :(得分:1)

validateUsernameUnique()似乎也出现了错误。您键入return this.userService.doesUsernameExist(control.value).then()...,它将在请求完成之前返回函数。

return之前尝试不使用this.userService.doesUsernameExist(...)

如果你仍然收到错误,我猜这是因为尝试在null上调用Object.keys()。在执行control.errors

之前,请检查Object.keys(control.errors)的值是多少