Access variables declared a component from a RxJS subscribe() function
This has nothing to do with rx or angular, and everything to do with Javascript and Typescript.
I assume you're familiar with the semantics of this
in the context of function invocations in Javascript (if not, there are no shortage of explanations online) - those semantics apply in the first snippet, of course, and that's the only reason this.message
is undefined inside subscribe()
there. That's just Javascript.
Since we're talking about Typescript:
Arrow functions are a Typescript construct intended (in part) to sidestep the awkwardness of these semantics by lexically capturing the meaning of this
, meaning that this
inside an arrow function === this
from the outer context.
So, if you replace:
.subscribe(function(location) {
//this != this from outer context
console.log(this.message); //prints 'undefined'
});
by:
.subscribe((location) => {
//this == this from the outer context
console.log(this.message); //prints 'success'
});
You'll get your expected result.
As an alternative to @drewmoore's answer, if you wish to have external functions you can do:
.subscribe((location) => dataHandler(location), (error) => errorHandler(error));
....
const dataHandler = (location) => {
...
}
By externalising the errorHandler
function, it can be used in multiple places (ie. subscriptions). By having as (fat) arrow functions your code will capture the 'this' context (as discussed in @Drewmoore's answer).
What is lacking is the ability to write the following and have handled like an arrow function. The following works and passes the argument implicitly. Unfortunately AFAIK you cannot capture the this
context (perhaps use bind
to achieve this, though that makes the code more verbose overall).
.subscribe(dataHandler, errorHandler);
This is soooo succinct! But alas won't work if the context is required.