1

Consider the following scenarios, where I'm passing a child Component a property updated later using a subscription to an RxJs Observable.

Angular is not detecting changes when not sending an anonymous function or biding the this context.

// Scenario 1
// Child component IS updated properly
this.someService.someObservable.subscribe((data) => {
    this.doSomething(data);
})

// Scenario 2
// Child component IS updated properly
this.someService.someObservable.subscribe(this.doSomething.bind(this))

// Scenario 3
// Child component is NOT updated properly
this.someService.someObservable.subscribe(this.doSomething)


private doSomething(data) {
    // this is executed on all the scenarios
    this.fieldPassedToChildComponent = data;
}

Why do we need to bind the context for angular to pick up the changes?

Danny Sandi
  • 657
  • 7
  • 27
  • If you don't, the `this` inside `doSomething` evaluates to the global object. – Ilia Choly Dec 29 '17 at 06:44
  • You mean Scenario 2 works but 3 doesn't? That makes sense, because of how `this` works. `this` is decided when the function is called, unless you bind it. – elclanrs Dec 29 '17 at 06:44
  • @elclanrs you are right, edited it – Danny Sandi Dec 29 '17 at 06:45
  • This may be a duplicate since it is a very common question. https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback – elclanrs Dec 29 '17 at 06:45
  • @elclanrs yeah, I was just wondering why the this context is needed, and why I can't just pass my function as the first argument. – Danny Sandi Dec 29 '17 at 06:46
  • @CodeProX arrow functions don't create separate context and that's why it works. take a look at 'No Separate this' section here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions – dee zg Dec 29 '17 at 06:47
  • Ok, Im referencing this inside doSomething thats why I need context. Thanks you all – Danny Sandi Dec 29 '17 at 06:48

1 Answers1

2

The problem with third case:

// Scenario 3
// Child component is NOT updated properly
this.someService.someObservable.subscribe(this.doSomething)

is that you cannot be sure what this keyword contains in your doSomething function on this line: this.fieldPassedToChildComponent = data;. It really depends how subscribe method calls your callback.

If you take a look in source code of subscribe you could find how the callback method is called and therefore what this is set to. My guess would be undefined. But could be anything. Therefore don't use this way.

Martin Nuc
  • 5,604
  • 2
  • 42
  • 48