javascript - TypeError: no es una función clase de typescript
Estoy recibiendo el siguiente error en mi clase de TypeScript y no puedo entender por qué. Todo lo que estoy haciendo es intentar llamar a una función auxiliar pasando el token.
Error :
error al publicar: TypeError: this.storeToken no es una función(…)
Clase :
/**
* Authentication Service:
*
* Contains the http request logic to authenticate the
* user.
*/
import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import 'rxjs/Rx';
import { Observable } from 'rxjs/Observable';
import { AuthToken } from './auth-token.service';
import { User } from '../../shared/models/user.model';
@Injectable()
export class Authenticate {
constructor(
private http: Http,
private authToken: AuthToken
) {}
post(user: User): Observable<any> {
let url = 'http://localhost:4000/';
let body = JSON.stringify(user);
let headers = new Headers({ 'content-type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(url + 'login', body, options)
.map(this.handleData)
.catch(this.handleError);
}
private storeToken(token: string) {
this.authToken.setToken(token);
}
private handleData(res: Response) {
let body = res.json();
this.storeToken(body.token);
return body.fields || {};
}
private handleError(error: any) {
console.error('post error: ', error);
return Observable.throw(error.statusText);
}
}
Soy nuevo en TypeScript, así que estoy seguro de que me estoy perdiendo algo ridículamente simple. Cualquier ayuda sería genial.
Gracias.
Respuesta #1
Debería ser de cualquiera de estas maneras (usando Function.prototype.bind):
return this.http.post(url + 'login', body, options)
.map(this.handleData.bind(this))
.catch(this.handleError.bind(this));
O (usando funciones flecha):
return this.http.post(url + 'login', body, options)
.map((res) => this.handleData(res))
.catch((error) => this.handleError(error));
Lo que pasa es que estás pasando una referencia a tu método, pero no está ligada a un this específico, por lo que cuando se ejecuta el método, el this en el cuerpo de la función no es la instancia de la clase, sino el alcance que ejecuta el método.
Cada uno de esos ayuda a mantener el contexto adecuado para this, pero de una manera diferente.
Editar
Otra opción es:
export class Authenticate {
...
private handleData = (res: Response) => {
...
}
private handleError = (error: any) => {
...
}
}
De esta manera, los "métodos" ya están vinculados, pero en este caso no formarán parte del prototipo y, de hecho, se convertirán solo en propiedades de tipo función.
Por ejemplo:
class A {
method1() { }
method2 = () => {}
}
Compila a:
// es5
var A = (function () {
function A() {
this.method2 = function () { };
}
A.prototype.method1 = function () { };
return A;
}());
// es6
class A {
constructor() {
this.method2 = () => { };
}
method1() { }
}
Debido a eso, method2 no puede ser (fácilmente) sobreescrito, así que ten cuidado con esta implementación.
