7

There are a lot of examples using the Observable.subscribe() function from AngularIO. Anyhow, I was only able to see anonymous functions inside as in:

bar().subscribe(data => this.data = data, ...);

If I try to hand in a function of the same class like here:

updateData(myData : DataType[]) {
   this.data = data;
}
...
bar().subscribe(this.updateData, ...);

Then the this object in line 2 doesn't refer to the current object anymore. This is probably some JavaScript logic that I don't understand. I know that you can bind an object to a function, is this what I have to do? Is this best practice? How would one usually resolve this issue (I'd like to avoid having a big anonymous function inside the subscribe().

user2084865
  • 625
  • 1
  • 7
  • 18

2 Answers2

16

You can wrap it inside an arrow function which will capture the correct this:

bar().subscribe((myData) => this.updateData(myData), ...);

Or use Function.bind which will also bind the correct context:

bar().subscribe(this.updateData.bind(this), ...);

But be aware that Function.bind returns any which will make you lose type checking in TypeScript. See https://github.com/Microsoft/TypeScript/issues/212

Saravana
  • 37,852
  • 18
  • 100
  • 108
  • You could also hide the messy details in a helper function using [`Function.call`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/call): `private subscribeBar(onDataChanged: (myData: any) => void): void { bar().subscribe((myData) => onDataChanged.call(this, myData)); }` that you would call like this: `this.subscribeBar(this.updateData);` This is particularly useful if you also need to pass extra arguments or save the subscription(s) to unsubscribe at a later occasion, and to be able to assert properly in your unit tests. – EriF89 Sep 18 '20 at 14:21
0

This is related to the fat arrow behavior.

You can find more here (in the "this and fat arrow" topic, about half the page)