Reputation: 59
I have written down a component and a service to show the detail of some object, however when subscribing and seeing in console it shows undefined. I have tried it a lot, any help would be appreciated.
I have shown all both component and service below to see if i am making any mistake here.
My component is below:-
import { Component, Input } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
import { filter, map } from 'rxjs/operators';
import { HeroService } from '../heroes/hero.service';
import { Hero } from '../hero';
@Component ({
selector : 'app-hero-detail',
templateUrl : './hero-detail.component.html'
})
export class HeroDetailComponent {
//@Input() hero : Hero;
hero : Hero;
constructor(
private route: ActivatedRoute,
private heroService: HeroService,
private location: Location
) {}
ngOnInit(): void {
this.getHero();
}
getHero(): void {
const id = +this.route.snapshot.paramMap.get('id');
this.heroService.getHero(id).map(hero => {this.hero = hero;console.log(hero);}).subscribe();
}
goBack(): void {
this.location.back();
}
}
My service is as below:-
import { HttpClient } from "@angular/common/http";
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/observable';
import { of } from 'rxjs/observable/of';
import 'rxjs/add/operator/find';
import 'rxjs/add/operator/map';
import { Hero } from '../hero';
import { MessageService } from './message.service';
@Injectable()
export class HeroService {
hero : Hero;
private heroesUrl = 'assets/api/mock-heroes.json';
constructor(private _http: HttpClient, public messageService : MessageService) { }
getHeroes(): Observable <Hero[]> {
this.messageService.add('HeroService: fetched heroes');
return this._http.get<Hero[]>(this.heroesUrl);
//return of(HEROES);
}
getHero(id: number): Observable<Hero> {
// Todo: send the message _after_ fetching the hero
this.messageService.add(`HeroService: fetch hero id=${id}`);
return this._http.get<Hero>(this.heroesUrl).find(hero => hero.id === id);
}
}
Here is my data set:-
[
{ "id": "11", "name": "Mr. Nice" },
{ "id": "12", "name": "Narco" },
{ "id": "13", "name": "Bombasto" },
{ "id": "14", "name": "Celeritas" },
{ "id": "15", "name": "Magneta" },
{ "id": "16", "name": "RubberMan" },
{ "id": "17", "name": "Dynama" },
{ "id": "18", "name": "Dr IQ" },
{ "id": "19", "name": "Magma" },
{ "id": "20", "name": "Tornado" }
]
Below is my template:-
<div *ngIf="hero">
<h2>{{ hero.name | uppercase }} Details</h2>
<div><span>id: </span>{{hero.id}}</div>
<div>
<label>name:
<input [(ngModel)]="hero.name" placeholder="name">
</label>
<button (click)="goBack()">go back</button>
</div>
Upvotes: 0
Views: 635
Reputation: 692151
Your JSON contains an array of Heroes. So
return this._http.get<Hero>(this.heroesUrl).find(hero => hero.id === id)
can't possibly be correct: the HTTP observable emits a single event, which is an array of heroes. It does not, as your code expects, emit multiple events which are each one Hero.
What is should be is
return this._http.get<Array<Hero>>(this.heroesUrl)
.map(heroes => heroes.find(hero => hero.id === id));
Also, the line
this.heroService.getHero(id).map(hero => {this.hero = hero;console.log(hero);}).subscribe();
should really be
this.heroService.getHero(id).subscribe(hero => this.hero = hero);
You're abusing map()
, which should be used to transform an event into something else, and not to produce side-effects.
Upvotes: 1