typescript - Acceder a 'this' dentro de una Promesa
En la función de TypeScript a continuación, 'this' no se resuelve como la instancia de EmailValidator. ¿Cómo puedo corregir esta función para que se resuelva a la instancia correcta de EmailValidator y, a su vez, para que pueda acceder a _registerServices?
class EmailValidator {
constructor(private _registerServices: RegisterServices) { }
isAvailable(c: AbstractControl): Promise<ValidationResult> {
let q = new Promise((resolve, reject) => {
this._registerServices.emailIsAvailable(antiForgeryToken(), c.value)
.then(result => {
// Need to actually check the result.
resolve({ "emailtaken": true })
},
error => {
// Need to communicate the server error? Probably not.
resolve({ "servererror": true })
});
});
return q;
}
}
Respuesta #1
Estás perdiendo this, porque estás pasando alrededor de isAvailableEmail como una función "cruda" aquí:
email: ['', Validators.required, this._emailValidator.isAvailableEmail]
Puedes solucionar esto vinculándolo a this (usando la flecha gorda):
email: ['', Validators.required,
(control) => { this._emailValidator.isAvailableEmail(control) }
]
Respuesta #2
Resultó que la referencia 'this' no estaba definida incluso si se usaba de la siguiente manera:
class EmailValidator {
constructor(private _registerServices: RegisterServices) { }
isAvailable(c: AbstractControl): EmailValidator {
return this; // 'This' is undefined!
}
}
Supongo que esto tiene algo que ver con cómo se llamó al método, quizás pasando un método no estático donde se esperaba un método estático:
...
this.registerForm = fb.group({
email: ['', Validators.required, this._emailValidator.isAvailableEmail],
password: ['', Validators.compose([Validators.required, Validators.minLength(8)])],
phoneNumber: ['', Validators.required],
country: ['', Validators.required]
});
...
Si alguien pudiera ofrecer alguna orientación sobre lo que está ocurriendo aquí, sería fantástico.
Mi Solución
Reorganicé mi código y produje lo siguiente:
class EmailValidator {
static isAvailableEmail(services: RegisterServices): (AbstractControl) => Promise<ValidationResult> {
let g = (c: AbstractControl) => {
return new Promise((resolve, reject) => {
services.emailIsAvailable(antiForgeryToken(), c.value)
.then(result => {
// Need to actually check the result.
resolve({ "emailtaken": true })
},
error => {
// Need to communicate the server error? Probably not.
resolve({ "servererror": true })
});
});
};
return g;
}
}
Y enmendó su uso:
...
this.registerForm = fb.group({
email: ['', Validators.required,
EmailValidator.isAvailableEmail(this._registerService)],
password: ['', Validators.compose([Validators.required, Validators.minLength(8)])],
phoneNumber: ['', Validators.required],
country: ['', Validators.required]
});
...
Que funciona correctamente.
