最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - TypeError: is not a function typescript class - Stack Overflow

programmeradmin2浏览0评论

I'm getting the following error in my typescript class and cannot understand why. All I am doing is trying to call a helper function passing the token.

Error:

post error: TypeError: this.storeToken is not a function(…)

Class:

/**
 * 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);
  }
}

I am new to typescript so I'm sure I am missing something ridiculously simple. Any assist would be great.

Thanks.

I'm getting the following error in my typescript class and cannot understand why. All I am doing is trying to call a helper function passing the token.

Error:

post error: TypeError: this.storeToken is not a function(…)

Class:

/**
 * 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);
  }
}

I am new to typescript so I'm sure I am missing something ridiculously simple. Any assist would be great.

Thanks.

Share Improve this question edited Jan 28, 2020 at 21:56 Chris Stillwell 10.5k10 gold badges74 silver badges81 bronze badges asked Dec 5, 2016 at 0:24 Aaron BalthaserAaron Balthaser 2,6223 gold badges38 silver badges61 bronze badges 1
  • I think this response would help stackoverflow.com/a/60789956/6109900 – Talabi Opemipo Commented May 6, 2023 at 12:25
Add a comment  | 

1 Answer 1

Reset to default 21

It should either be (using Function.prototype.bind):

return this.http.post(url + 'login', body, options)
      .map(this.handleData.bind(this))
      .catch(this.handleError.bind(this));

Or (using arrow functions):

return this.http.post(url + 'login', body, options)
      .map((res) => this.handleData(res))
      .catch((error) => this.handleError(error));

What happens is that you are passing a reference to your method but it's not bound to a specific this, so when the method is executed the this in the function body isn't the instance of the class but the scope that executes the method.

Each of of those help keep the right context for this, but in a different way.


Edit

Another option is:

export class Authenticate {
    ...

    private handleData = (res: Response) => {
        ...
    }

    private handleError = (error: any) => {
        ...
    }
}

In this way the "methods" are already bound, but in this case they won't be part of the prototype, and will in fact become just properties of type function.
For example:

class A {
    method1() { }
    method2 = () => {}
}

Compiles to:

// es5
var A = (function () {
    function A() {
        this.method2 = function () { };
    }
    A.prototype.method1 = function () { };
    return A;
}());

// es6
class A {
    constructor() {
        this.method2 = () => { };
    }
    method1() { }
}

Because of that method2 can't be (easily) overriden, so beware of this implementation.

发布评论

评论列表(0)

  1. 暂无评论