0

I am using a library that has the following definition in the d.ts file.

export function read(success?: (data: any, response: Response) => void);

I have the following class which works fine if the method is called with an Arrow function.

export class App {
  private async getData(): Promise<void> {
    lib.read((data, response) => {
      console.log(data);
    });
  }
}

However, if I try to pull the method into a class method, it does not work. When I step into the read method of library, it says that it is undefined.

export class App {
  private async onSuccess(data, response) {
    console.log(data);
  }      

  private async getData(): Promise<void> {
    lib.read(this.onSuccess)
  }
}

Any ideas why? Thanks!

wm_
  • 269
  • 2
  • 4
  • 10
  • Does this answer your question? [How to access the correct \`this\` inside a callback?](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) – VLAZ Jan 02 '21 at 09:45
  • Also relevant: [How does the “this” keyword work?](https://stackoverflow.com/q/3127429) – VLAZ Jan 02 '21 at 09:46
  • @VLAZ Thanks! I will spend some time reading it. – wm_ Jan 02 '21 at 10:05

1 Answers1

1

use arrow function always, that will help you get the right this object:

export class App {
  private async onSuccess(data, response) {
    console.log(data);
  }      

  private getData = async (): Promise<void> => {
    lib.read(this.onSuccess)
  }
}

Notice the change on getData declaration

I would advocate for not using classes but if you do always use arrow functions when you need the this coming into play.

Jose Greinch
  • 394
  • 2
  • 13
  • Thanks! Coming from .Net background, it is all a little confusing and feels weird that I have to purely define my methods using "arrow functions" to get the desired behaviour. – wm_ Jan 02 '21 at 10:04
  • Are there any disadvantage in using arrow functions as class methods? For example, from defining an interface which might make testing/mocking the class harder? – wm_ Jan 02 '21 at 10:08
  • no disadvantages at all. you will have to transpile the code as it's a newer function but that's something you are probably doing already :) `this` keyword is confusing but arrow functions always get the job done – Jose Greinch Jan 02 '21 at 14:53
  • 1
    @wm_ There is a disadvantage to using "arrow methods" in that they become *properties* on each instance. So, if you have one class that produces a thousand instances from, you get a thousand copies of all methods on that class. So, with three methods, that's three thousand extra objects floating around. When defined as a normal method, the functions are added to the prototype and all instances inherit it from there. So, the same situation as above but using normal methods, you only have three methods in memory in total, with another thousand objects all sharing them. – VLAZ Jan 02 '21 at 22:08
  • there's a small memory drawback but not meaningful enough to discourage its usage. You have to look at each particular scenario. memory is getting garbage collected automatically so when the class is not used it will be fred from the memory. – Jose Greinch Jan 02 '21 at 22:22
  • if we are to be that picky I wouldn't use classes at all in Javascript, there's just sugar syntax – Jose Greinch Jan 02 '21 at 22:23
  • Thanks for all the feedback both. @VLAZ If I do not want to use "arrow methods" and want to use class methods, what can I do to fix the code above? – wm_ Jan 03 '21 at 09:49
  • Actually, after reading your links again, @VLAZ, I realized that I just need to do a ".bind(this)" instead. – wm_ Jan 03 '21 at 14:41