Getting data from Web API in Angular 2

31,225

In my case the issue was related to the visual studio 2015 bug. There was nothing wrong with the code itself. Sometimes changes made in vs were not refreshed in the browser. Updating vs to the latest version helped.

Share:
31,225
SteppingRazor
Author by

SteppingRazor

You can run but you can't hide.

Updated on October 13, 2020

Comments

  • SteppingRazor
    SteppingRazor over 3 years

    Thanks to tutorial on Angular 2 page called "Tour of Heroes", I managed to create a simple Angular 2 application. Then using Enitity Framework I decided to create a database. And fill the list of heroes from it (not from the file). I created Web Api Controller and added simple get method. Then in hero.service.ts I call this method in order to get list of heroes. When I lunch my app it shows the list of heroes but without any values (name and id are blank). When I debug my application in the browser I can see this.heroes object in heroes.component.ts contains right data. So what is going on? Why aren't name and id showing?

    hero.service.ts:

    import {Injectable} from 'angular2/core';
    import {HEROES} from './mock-heroes';
    import {Hero} from './hero';
    import {Http, Response} from 'angular2/http';
    import 'rxjs/Rx';
    import {Observable}     from 'rxjs/Observable';
    
    @Injectable()
    export class HeroService {
    
        public values: any;
    
        constructor(public _http: Http) { }
    
        private _heroesUrl = 'http://localhost:61553/api/values'; // URL to web api
    
        getHeroes() {
            return this._http.get(this._heroesUrl)
                .map(res => <Hero[]>res.json())
                .catch(this.handleError);
        }
        private handleError(error: Response) {
            console.error(error);
            return Observable.throw(error.json().error || 'Server error');
        }
    }
    

    heroes.component.ts:

    import {Component, OnInit} from 'angular2/core';
    import {Router} from 'angular2/router';
    
    import {Hero} from './hero';
    import {HeroDetailComponent} from './hero-detail.component';
    import {HeroService} from './hero.service';
    
    @Component({
        selector: 'my-heroes',
        templateUrl: 'templates/heroes.component.html',
        styleUrls: ['styles/heroes-component.css'],
        directives: [HeroDetailComponent]
    })
    
    export class HeroesComponent implements OnInit {
    
        constructor(private _heroservice: HeroService, private _router: Router) { }
    
        errorMessage: string;
        public heroes: Hero[];
    
        selectedHero: Hero;
    
        ngOnInit() {
            this.getHeroes();
        }
    
        onSelect(hero: Hero)
        {
            this.selectedHero = hero;
        }
    
        getHeroes() {
            this._heroservice.getHeroes()
                .subscribe(
                value => this.heroes = value,
                error => this.errorMessage = <any>error);
        }
    
        gotoDetail() {
            this._router.navigate(['HeroDetail', { id: this.selectedHero.Id }]);
        }
    }
    

    heroes.component.html:

    <h2>My Heroes</h2>
    <ul class="heroes">
        <li *ngFor="#hero of heroes" [class.selected]="hero === selectedHero" (click)="onSelect(hero)">
            <span class="badge">{{hero.Id}}</span> {{hero.Name}}
        </li>
    </ul>
    <div *ngIf="selectedHero">
        <h2>
            {{selectedHero.Name | uppercase}} is my hero
        </h2>
        <button (click)="gotoDetail()">View Details</button>
    </div>
    

    hero.ts:

    export class Hero {
        Id: number;
        Name: string;
    }
    

    Web API Controller:

    using Microsoft.AspNet.Mvc;
    using System.Collections.Generic;
    using TestApplicationDataAccess;
    using TestApplicationDataAccess.Entities;
    
    namespace WebApplication2.Controllers
    {
        [Route("api/[controller]")]
        public class ValuesController : Controller
        {
            private readonly TestAppDbContext _dbContext;
    
            public ValuesController(TestAppDbContext dbContext)
            {
                _dbContext = dbContext;
            }
    
            // GET: api/values
            [HttpGet]
            public IEnumerable<Hero> Get()
            {
                return _dbContext.Heroes;
            }
        }
    }
    

    Hero Entity:

    namespace TestApplicationDataAccess.Entities
    {
        public class Hero
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
    }
    

    JSON retrieved from WEB API Controller:

    [{"Id":1,"Name":"Superman"}]
    
  • SteppingRazor
    SteppingRazor about 8 years
    No, Elvis operator won't help here. The console does not throw any error so the value is not null at least the hero.
  • micronyks
    micronyks about 8 years
    {value => this.heroes = value, console.log(this.heroes)},... what do you get in console?
  • micronyks
    micronyks about 8 years
    hmm you are not getting data from api. check that first.
  • SteppingRazor
    SteppingRazor about 8 years
    So how come i got the result: [{"Id":1,"Name":"Superman"}], and when i debug i can see in heroes object that it contains the array with 1 element with exact same values: 1 and Superman ?
  • micronyks
    micronyks about 8 years
    but you just said, its undefined
  • SteppingRazor
    SteppingRazor about 8 years
    Yes in console it says undefined. But in debugger I can see this: image
  • micronyks
    micronyks about 8 years
    how its possible? Can you explain me?
  • micronyks
    micronyks about 8 years
    Check my update. Plus plnkr.co/edit/O5vXFcDnb3tZ7FaqAyam?p=preview if you could reproduce here something. I know since you use web api, it is not possible to go with plunker but still if you could come up with something by forking my plunker.