jayscript
jayscript

Reputation: 319

Using RxJS subscribe operator in Angular 2 observable

Here is my service TypeScript file.

import {Injectable} from '@angular/core';
import {Http, HTTP_PROVIDERS, Request, RequestOptions, Response, Headers} from '@angular/http';
import {Observable} from 'rxjs/Observable';

@Injectable()
export class CarService {
    constructor(private http: Http) { }
    Url: string = 'url/of/api';
    getCar(){
        var headers = new Headers();
            headers.append('API-Key-For-Authentification', 'my_own_key_goes_here');
            headers.append('Accept', 'application/json');
        var options = new RequestOptions({ headers: headers })
        return this.http.get(this.Url, options)
            .map((res: Response) => res.json())
    }
}

Above gets injected to the component bellow.

import {Component} from '@angular/core';
import {CarService} from 'path/to/car.service';

@Component({
    selector: 'home',
    providers: [ CarService ],
    template: `
        <div>
            <button (click)="getCar()">Get Car</button>
            <h2>The car has {{ tiresCount }} tires.</h2>
        </div>
    `
})
export class Home {
    tiresCount: number;
    constructor(private carService: CarService) { }
    getCar() {
        this.carService.getCar()
            .subscribe(function(data){
                this.tiresCount = data.tires.count;
                console.log(this.tiresCount); // 4
        };
        console.log(this.tiresCount); // undefined
    }
}

What I am trying to do is to display the number of tires in the view of the Home component when the button is clicked. The problem is that, when I console.log(this.tiresCount) inside the .subscribe parentheses, it logs 4 but logs undefined outside of it. This means that the local property tiresCount did not get the new value so that it won't display anything in the view.

I suspect I am missing something obvious. Or perhaps, the understanding of Observables and/or RxJS is needed here as I am new to them.

Upvotes: 4

Views: 8473

Answers (1)

Abdulrahman Alsoghayer
Abdulrahman Alsoghayer

Reputation: 16540

Use lambda expression "aka, arrow function" instead of function(){..} in your subscribe method. When using function(){...}, this inside it will refer to the function itself instead of the Home component class.

getCar() {
    this.carService.getCar()
            .subscribe(data => {
                this.tiresCount = data.tires.count;
                console.log(this.tiresCount); // 4
    });
    console.log(this.tiresCount); // undefined
}
someWhereElse(){
    console.log(this.tiresCount); // 4 , only after getCar().subscribe() resolves 
}

Upvotes: 5

Related Questions