Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError: is not a function typescript class

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.

like image 529
Aaron Avatar asked Dec 05 '16 00:12

Aaron


People also ask

Is not a function TypeScript error?

A TypeError: "x" is not a function occurs when a function is called on an object that does not contain the called function. When calling a built-in function that expects a callback function argument, which does not exist. When the called function is within a scope that is not accessible.

How do I fix uncaught TypeError is not a function?

We can fix this error by using jQuery() . We can use $() freely inside of our jQuery object after utilizing it. jQuery(document). ready(function($){ var allParagraphTags = $( 'p' ); });

How do you handle uncaught TypeError?

Another way to handle TypeError is to use the alert function. The alert function will display a message to the user and then stop the execution of the JavaScript code. In the following code example, the alert function is used to display a message when the y variable is not a number.


1 Answers

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.

like image 54
Nitzan Tomer Avatar answered Sep 21 '22 15:09

Nitzan Tomer