我需要一些帮助。我认为我误解了Subscriptions and Observables,但我发现Angular文档没有特别的帮助。
我正在创建用来检查用户名是否可用的validationService。 ValidationService在表单提交时调用,如果用户名不可用,则会显示一条错误消息。问题是,我必须提交两次表单才能使其正常工作。
validationService对后端进行http调用,返回一个布尔值。我有一个本地变量“ availableUsername”,我要将结果设置为该变量,以便可以在其他地方使用它。在订阅函数内部,它工作正常,我得到了结果并将其设置为该变量。但是当我离开订阅方法的范围时,该变量未定义。但是,当我再次调用Submit时,它可以工作。
我在下面添加了validationService和userService。
validationService.ts
import { Injectable } from '@angular/core';
import { FormControl } from '@angular/forms';
import { AlertService } from './../services/alert.service';
import { UserService } from './../services/user.service';
@Injectable({
providedIn: 'root'
})
export class ValidationService {
availableUsername: boolean;
availableEmail: boolean;
constructor(
private alertService: AlertService,
private userService: UserService
) { }
validateUsername(controls: any): boolean {
const username = controls.username.value;
this.isUsernameAvailable(username);
if (!this.availableUsername) {
this.alertService.error('This username is already taken', false);
return true;
}
return false;
}
private isUsernameAvailable(username: string) {
if (username === undefined || username === '') {
return;
}
this.userService.isUserNameAvailable(username)
.subscribe((result) => {
this.availableUsername = result;
},
error => {
this.alertService.error(error);
return;
});
}
}
userService.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from './../../environments/environment';
@Injectable({ providedIn: 'root' })
export class UserService {
apiUrl: string = environment.apiUrl;
constructor(private http: HttpClient) { }
isUserNameAvailable(username: string) {
return this.http.get<boolean>(`${this.apiUrl}/users/checkUsernameAvailability/${username}`);
}
}
答案 0 :(得分:0)
this.isUsernameAvailable(username);
在执行完以上代码后,它将异步运行,因此在为this.availableUsername = result;
赋值之前
通过订阅,以下代码将运行
if (!this.availableUsername) {
this.alertService.error('This username is already taken', false);
return true;
}
return false;
}
要避免发生这种情况,请检查订阅中的这种情况
this.userService.isUserNameAvailable(username)
.subscribe((result) => {
this.availableUsername = result;
},
error => {
this.alertService.error(error);
return;
}
()=>{
if (!this.availableUsername) {
this.alertService.error('This username is already taken', false);
}
}
);
}
}
答案 1 :(得分:-1)
代码中的问题是您尝试异步流同步
availableUsername
属性值仅在调用subscribe
之后才设置,该调用将在if (!this.availableUsername)
之后很长时间。
在这种情况下,您可以使用为这些情况构建的asyncValidartor。
另一种(不建议使用的方法)是使代码使用async
和await
同步运行。