响应未定义

时间:2017-09-29 19:28:21

标签: json angular asp.net-web-api asp.net-web-api2

我已经按照英雄教程进行操作,现在我正尝试从MVC web api rest服务中检索我的英雄数据。我修改了我的hero.service中的GetHeroes()方法:

import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';

import { HttpClient } from '@angular/common/http';

export class Hero {
  constructor(public Id: number, public HeroName: string, public Location: string) { }
}

@Injectable()
export class HeroService {

  constructor(private http: HttpClient) { }

  results: Observable<string[]>;

  private location: string;

  getHeroes(): Observable<Hero[]> {
      return this.http.get('http://localhost:50125/api/heroes')
          .map((response: Response): Hero[] => JSON.parse(response['_body']))
          .catch(error => Observable.throw(error));
  }

  getHero(id: number | string) {
    return this.getHeroes()
      // (+) before `id` turns the string into a number
      .map(heroes => heroes.find(hero => hero.Id === +id));

  }

}

我从我的组件调用服务方法:

import 'rxjs/add/operator/switchMap';
import { Observable } from 'rxjs/Observable';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';

import { Hero, HeroService } from './hero.service';

@Component({
  template: `
    <h2>HEROES</h2>
    <ul class="items">
      <li *ngFor="let hero of heroes$ | async"
        [class.selected]="hero.Id === selectedId">
        <a [routerLink]="['/hero', hero.Id]">
          <span class="badge">{{ hero.Id }}</span>{{ hero.HeroName }}
        </a>
      </li>
    </ul>
  `
})
export class HeroListComponent implements OnInit {
  heroes$: Observable<Hero[]>;

  private selectedId: number;

  constructor(
    private service: HeroService,
    private route: ActivatedRoute
  ) {}

  ngOnInit() {
    this.heroes$ = this.route.paramMap
      .switchMap((params: ParamMap) => {
        // (+) before `params.get()` turns the string into a number
        this.selectedId = +params.get('id');
        return this.service.getHeroes();
      });
  }

}

My Heroes api控制器看起来像这样:

using HeroesService.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Newtonsoft.Json;

namespace HeroesService.Controllers
{
    public class HeroesController : ApiController
    {
        // GET: api/Heroes
        public List<Hero> Get()
        {
            List<Hero> heroes = new List<Hero>();

            Hero superman = new Hero();
            superman.Id = 10;
            superman.HeroName = "Superman";
            superman.Location = "Los Angeles, California";
            heroes.Add(superman);

            Hero batman = new Hero();
            batman.Id = 11;
            batman.HeroName = "Batman";
            batman.Location = "Chicago, Illinois";
            heroes.Add(batman);

            return heroes;
        }
    }
}

我可以在Chrome的“网络”标签中看到如下所示的数据:

[{"Id":10,"HeroName":"Superman","Location":"Los Angeles, California"},{"Id":11,"HeroName":"Batman","Location":"Chicago, Illinois"}]

不幸的是,我收到一个看起来像这样的错误(可能意味着响应数据未定义):

  

ERROR SyntaxError:位于0的JSON中的意外标记u       在JSON.parse()       在MapSubscriber.eval [as project](hero.service.ts:34)       在MapSubscriber._next(map.ts:75)       在MapSubscriber.Subscriber.next(Subscriber.ts:95)       在MapSubscriber._next(map.ts:80)       在MapSubscriber.Subscriber.next(Subscriber.ts:95)       在FilterSubscriber._next(filter.ts:95)       在FilterSubscriber.Subscriber.next(Subscriber.ts:95)       在MergeMapSubscriber.notifyNext(mergeMap.ts:151)       在InnerSubscriber._next(InnerSubscriber.ts:17)

2 个答案:

答案 0 :(得分:2)

您可以利用HttpClient.get能够为您使用JSON数据这一事实。使用以下代码告诉HttpClient响应类型为Hero[],并放弃对mapcatch的调用:

 return this.http.get<Hero[]>('http://localhost:50125/api/heroes');

由于undefined没有属性response,我希望您收到_body

答案 1 :(得分:2)

您正在使用新的HttpClient,但使用旧的http。

getHeroes(): Observable<Hero[]> {
  return this.http.get('http://localhost:50125/api/heroes')
    .map((response: Response): Hero[] => JSON.parse(response['_body']))
    .catch(error => Observable.throw(error));
}

应该是

getHeroes(): Observable<Hero[]> {
  return this.http.get<Hero[]>('http://localhost:50125/api/heroes');
}

你可以订阅它,你不需要JSON.parse它。