0

I have this situation of a typescript class. This is a minimal example.

class Example {
    private foo(arg: string){ 
        console.log(arg);
    }
    private list = [
        {
            name: 'Hello'
            callableFunction: function(x: string) {
                this.foo(x);
            }
        }
    ]
    public execute() {
        this.list.forEach(listElement => {
            listelement.callableFunction('Hello Foo Bar');
        })
    }
}

I am getting _this is not a function

The translated js code looks like

...
callableFunction: function (x) {
    var _this = this;
    _this.foo(x); // <-- error here
    

My tsconfig is fairly standard i think...

{
    "compilerOptions": {
        "outDir": "./build",
        "allowJs": true,
        "target": "es5",
        "moduleResolution": "node",
        "strictNullChecks": true
    }
}

I know that there exist lots of posts on this topic, still I could nit find any post describing my situation with class methods.

Vadim Kotov
  • 7,103
  • 8
  • 44
  • 57
olidem
  • 1,239
  • 11
  • 28
  • The `this` inside the `callableFunction` doesn't refer to the class `Example` instance. What are you trying to achieve? – igg Feb 12 '20 at 12:44
  • If you make the function into a lambda, then `this` will probably do what you want. The semantics of `this` in Javascript (and hence, Typescript) are quite strange if you're used to class-based OOP. – kaya3 Feb 12 '20 at 12:45
  • 1
    @kaya3 You're correct but, to nitpick, they're both lambdas. – Aluan Haddad Feb 12 '20 at 13:35
  • 1
    Does this answer your question? [How does the "this" keyword work?](https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – Aluan Haddad Feb 12 '20 at 13:36

2 Answers2

3

You can fix the context issue with the fat arrow

 private list = [
        {
            name: 'Hello',
            callableFunction: (x: string) => {
                this.foo(x);
            }
        }
    ]
Murat Karagöz
  • 26,294
  • 9
  • 70
  • 97
1

Type this

class Example {
    private foo(arg: string) {
        console.log(arg)
    }
    private list = [
        {
            name: 'Hello',
            callableFunction: function(this: Example, x: string) {
                this.foo(x)
            }
        }
    ]
    public execute() {
        this.list.forEach(listElement => {
            listElement.callableFunction.call(this, 'Hello Foo Bar')
        })
    }
}

use arrow function

class Example {
    private foo(arg: string) {
        console.log(arg)
    }
    private list = [
        {
            name: 'Hello',
            callableFunction: (x: string) => {
                this.foo(x)
            }
        }
    ]
    public execute() {
        this.list.forEach(listElement => {
            listElement.callableFunction('Hello Foo Bar')
        })
    }
}
creanme
  • 11
  • 1