Я подписываюсь на службу HTTP-запросов в моем методе validateUsernameIsUnique
. Я пытаюсь манипулировать возвращаемым значением validateUsernameIsUnique()
на основе кода внутри подписки. Я прочитал несколько статей для начинающих об асинхронном поведении. Поэтому я знаю, что приведенный ниже код не работает, потому что return ret;
не определено. К сожалению, я не смог понять, как добиться того, что я пытаюсь сделать.
@Injectable()
export class ValidateService {
constructor(private _authService: AuthService) { }
...
validateUsernameIsUnique = (c: FormControl) => {
let ret;
if (c.value.length >= 3) {
this._authService.uniqueUser({ username: c.value }).subscribe(data => {
if (!data.success) { // Username already exists
ret = { usernameIsTaken: true };
}
else
ret = null;
})
return ret;
}
}
}
Служба аутентификации, на которую я подписываюсь, выглядит так:
import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import 'rxjs/add/operator/map';
@Injectable()
export class AuthService {
authToken: any;
user: any;
constructor(private _http: Http) { }
uniqueUser(user) {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this._http.post('http://localhost:3000/users/username', user, { headers: headers })
.map(res => res.json());
}
}
Обновление 1:
Измененный код, как указано в комментариях к
validateUsernameIsUnique = (c: FormControl) => {
if (c.value.length >= 3) {
return this._authService.uniqueUser({ username: 'zomh' }).map(res =>
{
if (!res.success) { // Username already exists
return { usernameIsTaken: true };
}
else
{
return null;
}
});
}
}
И звонок выглядит так
ngOnInit() {
this.frmRegisterUser = new FormGroup({
name: new FormControl('',[Validators.required]),
username: new FormControl('',[Validators.required, this._validateService.validateUsernameIsUnique, Validators.minLength(3), this._validateService.validateUsernamePattern]),
email: new FormControl('',[Validators.required, this._validateService.validateEmailPattern]),
password: new FormControl('',[Validators.required, Validators.minLength(6)]),
acceptTerms: new FormControl(false,[Validators.required])
});
Теперь я получаю объект, который выглядит так:
Извините, но я все еще не понимаю, где я могу найти сопоставленные возвращаемые значения, например. { usernameIsTaken: true }
Обновление 2 @pixelbits
Это не сработало сразу: я не знаю, как это правильно отлаживать?, так как console.logs не будет печататься по асинхронным причинам во внутренних функциях. Я попытался указать имя пользователя «zomh», которое уже есть в базе данных (не уникально).
uniqueName(): AsyncValidatorFn {
console.log('i am here');
return (control:AbstractControl): Promise<ValidationResult> => {
let q = new Promise<ValidationResult>(
(resolve, reject)=> {
var name = 'zomh';
if (name == '') {
resolve(null);
}
else {
this._authService.uniqueUser({ username: 'zomh' })
.map(t=>t.json())
.subscribe(response=> {
if (response.success === false) {
resolve(response);
}
else
resolve(null);
});
}
});
return q;
}
}
Я получаю "i am here"
в консоли, но это почти все. Я получаю нуль, хотя этого не должно быть с существующим именем пользователя. Я могу убедиться, что AuthService работает правильно (протестировал его с базовой подпиской и именем пользователя «zomh»).
.subscribe
асинхронный. Наблюдаемые в целом асинхронны, поэтому вы не можете возвращать их данные за пределы их области. - person Adam   schedule 24.02.2017