Observable service not working in component NgOnInIt - Angular2
Observable getHero service does not start at NgOnInIt in HeroDetail component.
I can use HTTP to get and display the datasheet and navigate to the detail page when the row is clicked. I then use the "id" url parameter to get the id, but the same does not work with the getHero function to get the data of a specific row.
The id shows up in the console, but the hero appears as undefined. I have tried many products but none have worked so far. Any help would be much appreciated.
Below is my code for reference.
hero.service.ts
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import { Hero } from './hero';
@Injectable()
export class HeroService {
heroes: Hero[];
hero: Hero;
private heroesUrl = 'SERVICE URL';
constructor (private http: Http) {}
getHeroes(): Observable<Hero[]> {
return this.http.get(this.heroesUrl)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json()['data'];
console.log(body);
return body || { };
}
private handleError (error: Response | any) {
// In a real world app, you might use a remote logging infrastructure
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
getHero(id: number): Observable<Hero> {
return this.getHeroes()
.map(heroes => heroes.find(hero => hero.cc_id == id));
}
}
hero-detail.component.ts
import { Component } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { HeroService } from './hero.service';
import { Hero } from './hero';
@Component({
template: `
<h2>INNER PAGE {{ this.id }}</h2>
`,
providers: [HeroService]
})
export class HeroDetailComponent {
errorMessage: string;
hero: Hero;
heroes: Hero[];
id: number;
mode = 'Observable';
constructor (
private service: HeroService,
private route: ActivatedRoute,
private router: Router
) {}
ngOnInit() { this.getHeroes() }
getHeroes() {
this.id = this.route.snapshot.params['id'];
console.log(this.id);
this.service.getHero(this.id).subscribe(hero => this.hero = hero);
console.log(this.hero);
}
}
source to share
When using Observables, the code outside the Observable is executed before the actual subscription block is executed, since Observables are asynchronous. The response from the server comes in a subscription callback. Try changing your code like this:
this.service.getHero(this.id).subscribe(hero => {
this.hero = hero; // assign the class variable values here
console.log(this.hero);
});
}
source to share