0

I'm new to JavaScript/TypeScript and am trying to figure out what's going on here.

class MyClass {

    constructor() {
        this.doThisEverySecond();
        setInterval(this.doThisEverySecond, 1000);  // Tried here
    }

    doThisEverySecond():void {
        console.log("Do some stuff");
        this.subroutineForOrganization();
        console.log("Do more stuff\n");
    }

    subroutineForOrganization():void {
        console.log("Doing many things");
    }
}

const foo:MyClass = new MyClass();
setInterval(foo.doThisEverySecond, 1000);  // And tried here

I want to call a function doThisEverySecond() and have it execute every x seconds; and for simple organizational purposes I have some of what it does pulled out into a subroutine, subroutineForOrganization().

Regardless of whether I call setInterval() in its constructor or immediately after its instantiated, I get the following error:

Do some stuff
Doing many things
Do more stuff

Do some stuff
D:\Webstorm Projects\Sonification\es5\src_ts\test.js:8
        this.subroutineForOrganization();
             ^

TypeError: this.subroutineForOrganization is not a function
    at Timeout.MyClass.doThisEverySecond [as _repeat] (D:\Webstorm Projects\Sonification\es5\src_ts\test.js:8:14)
    at Timeout.wrapper [as _onTimeout] (timers.js:417:11)
    at tryOnTimeout (timers.js:224:11)
    at Timer.listOnTimeout (timers.js:198:5)

Process finished with exit code 1

I don't understand why it runs just fine when called from the constructor the first time, but then has an error when its invoked with setInterval. How is it a function then, but not now? Is there some sort of JavaScript scope wizardry going on that I don't get?

Thanks!

SOLVED: Calling with an arrow function (as explained below) preserves the reference to this (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Lexical_this)

davidlav
  • 636
  • 5
  • 17
  • `this` isn't what you think it is. – Kevin B Jul 13 '16 at 22:18
  • Following the linked post above, this is what ended up working. All I needed to do was wrap the call in an anonymous function. Time to go read up on closures... `setInterval(() => this.doThisEverySecond(), 1000);` – davidlav Jul 13 '16 at 23:16

2 Answers2

0

Use the Function.prototype.bind function:

constructor() {
    this.doThisEverySecond();
    setInterval(this.doThisEverySecond.bind(this), 1000);  // Tried here
}
Nitzan Tomer
  • 155,636
  • 47
  • 315
  • 299
-1

I believe it is because you are not defining your functions correctly. Try this instead:

function doThisEverySecond() {
    console.log("Do some stuff");
    this.subroutineForOrganization();
    console.log("Do more stuff\n");
}

And:

function subroutineForOrganization() {
    console.log("Doing many things");
}
Skua
  • 19
  • 4