0

I am using Angular 4 as my frontend and Laravel 5.5 as my restful API. the backend seems fine wrt the problem, i can sent curl requests and get back exactly what i expect, a JSON with 2 key-value pairs:

[{"id":1,"name":"Mr. Nice"}]

When i try and do this with angular i get the following:

HERO: [object Object] HERO.ID: HERO.NAME

my service (I included a working get request just for reference):

getHeroes(): Observable<Hero[]> {
    return this.http.get<Hero[]>(this.heroesUrl).pipe(
        tap(heroes => this.log(`fetched heroes, ${this.heroesUrl}`)),
        catchError(this.handleError('getHeroes', []))
    );
}

/** ISSUE HERE */
getHero(id: number): Observable<Hero> {
    const url = `${this.heroesUrl}/${id}`;
    return this.http.get<Hero>(url).pipe(
        tap(_ => this.log(`fetched hero id=${id}, ${url}`)),
        catchError(this.handleError<Hero>(`getHero id=${id}`))
    );
}

the component:

import { Component, OnInit, Input } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
import { HeroService }  from '../hero.service';
import { Hero } from '../hero';

@Component({
    selector: 'app-hero-detail',
    templateUrl: './hero-detail.component.html',
    styleUrls: ['./hero-detail.component.css']
})
export class HeroDetailComponent implements OnInit {

    @Input() 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)
            .subscribe(hero => this.hero = hero);
    }

    goBack(): void {
        this.location.back();
    }
}

the template:

<div *ngIf="hero">
        <div>HERO: {{ hero }} HERO.ID: {{ hero.id }} HERO.NAME {{ hero.name }}</div>
        <h2>{{hero.name | uppercase}} Details</h2>
        <div><span>id: </span>{{hero.id}}</div>
        <div>
                <label>name:
                        <input [(ngModel)]="hero.name" placeholder="name">
                </label>
        </div>
</div>

<button (click)="goBack()">go back</button>

the class:

export class Hero {
    id: number;
    name: string;
}

From what i can tell for some reason angular is not recognizing the json as a single instance of the class Hero, the *ngIf= in the template does get triggered. the getHeroes function in the service works, it returns a multiple entries and i loop through them in the template, is there something fairly obvious that i am missing?

I am fairly new to angular so any help would be appreciated.

Thanks.

4
  • You could use ng-repeat to loop over the results, or make getHero return a single object. ng-if might always be true as well so possibly check for the length of the array. Commented Nov 26, 2017 at 11:48
  • You should subscribe on ngOnInit or use | async pipe in template. Commented Nov 26, 2017 at 12:45
  • So what does your getHero actually return (JSON) Is it what you have posted up in your question? Commented Nov 26, 2017 at 15:19
  • my json returns [{"id":1,"name":"Mr. Nice"}] but for some reason using Hero instead of Hero[] in the observable, angular does not convert it to the class Hero. i dont understand why, in angular's tutorial it works fine with an array of length 1... Commented Nov 26, 2017 at 22:42

1 Answer 1

1

What you are receiving is an object inside an array, which causes [object Object] in your view. What you want, is to extract that single hero from your response:

getHero(id: number): Observable<Hero> {
    const url = `${this.heroesUrl}/${id}`;
    return this.http.get<Hero[]>(url).pipe(
        map(heroes => heroes[0]) // here!
        tap(_ => this.log(`fetched hero id=${id}, ${url}`)),
        catchError(this.handleError<Hero>(`getHero id=${id}`))
    );
}
Sign up to request clarification or add additional context in comments.

2 Comments

that did it, another solution was to change what i was sending from the backend, single item vs array with 1 item in it. Thank you
You are welcome! Since it solved your issue, consider accepting the answer by clicking the grey tick under the voting of this answer, which marks the question as solved :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.