Búsqueda de sitios web

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.

Artículos relacionados