javascript - Acceder a variables declaradas en un componente desde una función subscribe() de RxJS
Puedo usar this.variable para acceder a variables en cualquier parte del componente, excepto dentro de funciones de RxJS como subscribe() o catch().
En el ejemplo a continuación, quiero imprimir un mensaje después de ejecutar un proceso:
import {Component, View} from 'angular2/core';
@Component({
selector: 'navigator'
})
@View({
template: './app.component.html',
styles: ['./app.component.css']
})
export class AppComponent {
message: string;
constructor() {
this.message = 'success';
}
doSomething() {
runTheProcess()
.subscribe(function(location) {
console.log(this.message);
});
}
}
Cuando ejecuto doSomething(), obtengo undefined. Este escenario se puede resolver usando una variable local:
import {Component, View} from 'angular2/core';
@Component({
selector: 'navigator'
})
@View({
template: './app.component.html',
styles: ['./app.component.css']
})
export class AppComponent {
message: string;
constructor() {
this.message = 'success';
}
doSomething() {
// assign it to a local variable
let message = this.message;
runTheProcess()
.subscribe(function(location) {
console.log(message);
});
}
}
Supongo que esto está relacionado con el this, sin embargo, ¿por qué no puedo acceder a this.message dentro de subscribe()?
Respuesta #1
Esto no tiene nada que ver con rx o angular, y todo que ver con Javascript y Typescript.
Supongo que estás familiarizado con la semántica de this en el contexto de las invocaciones de funciones en Javascript (si no, hay muchas explicaciones disponibles en línea); esas mismas semánticas se aplican en el primer fragmento, por supuesto, y esa es la única razón por la que this.message es undefined dentro de subscribe() allí. Eso es simplemente Javascript.
Ya que estamos hablando de Typescript: las funciones flecha son una construcción de Typescript destinada (en parte) a eludir las complicaciones de estas semánticas capturando léxicamente el significado de this, lo que significa que this dentro de una función flecha === this del contexto externo.
Entonces, si reemplazas:
.subscribe(function(location) {
//this != this from outer context
console.log(this.message); //prints 'undefined'
});
por :
.subscribe((location) => {
//this == this from the outer context
console.log(this.message); //prints 'success'
});
Obtendrás el resultado que esperas.
