Angular2 服务 Returns 未定义

Angular2 Service Returns Undefined

出于某种原因,我的服务无法正常工作。我潜伏了两天试图找到类似的问题,但它们不适合我的问题。

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 { CarObject } from './make';

@Injectable()
export class EdmundsService {
  private stylesurl = 'REDACTED';

 constructor(private http: Http) { }

 getCars(): Observable<CarObject[]> {
   return this.http.get(this.stylesurl)
   .map(this.extractData)
   .catch(this.handleError);
  }

  private extractData(res: Response) {
   let body = res.json();
   return body.data || { };
  }
  private handleError (error: Response | any) {
  // In a real world app, we 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);
  }

}

这些是我的 'models':

class Style {
  id: number;
  name: string;
  make: Make;
  model: Model;
  year: Year;
  submodel: Submodel;
  trim: string;
  states: string[];
  engine: Engine;
  transmission: Transmission;
  options: Options[];
  colors: Color[];
  drivenWheels: string;
  numOfDoors: string;
  squishVins: string[];
  categories: Categories;
  MPG: MPG;
  manufacturerOptionCode: string;
 }

export class CarObject {
styles: Style[];
stylesCount: number;
}

我的组件:

import { CarObject } from './make';
import { EdmundsService } from './edmunds-search-result.service';

@Component({REDACTED
providers: [EdmundsService] })


export class EdmundsSearchResultComponent implements OnInit {
  cars: CarObject[];
  errorMessage: string;



  constructor(private _edmundsService: EdmundsService) { }

   getCars(): void {
     this._edmundsService.getCars()
     .subscribe(
      cars => this.cars = cars,
      error =>  this.errorMessage = <any>error);
   }


  ngOnInit(): void {
   this.getCars();
  }

}

组件HTML: {{ cars.stylesCount |异步}}

示例 API 响应:http://pastebin.com/0LyZuPGW

错误输出:

EXCEPTION: Error in ./EdmundsSearchResultComponent class 
EdmundsSearchResultComponent - inline template:0:0 caused by: 
Cannot read    property 'stylesCount' of undefined
  1. CarObject 旨在匹配 API 响应,因此可以删除数组括号 ([])
  2. 尽管我密切关注英雄之旅 HTTP/Services 教程,但我不知道为什么这不会在我的模板上显示对象数据。

我想做的是从变量 'styleurl' 发出 HTTP 请求(我看到通过检查 chrome 开发工具中的 'Network' 选项卡成功发出请求。)使用这个 API 响应,我希望我的 CarObject 能够 'consume' json 响应,并且可供我的 component/template.

使用

在您的组件中,您保留了 car 属性,但您没有初始化它,所以它仍然是 undefined

在您的 HTML 呈现承诺尚未实现时,您的 car 仍然是 undefined 但您尝试从中访问 属性。

几个解决方案:

预设:

cars: CarObject = new CarObject(); // or <CarObject>{}

在模板中使用 elvis 运算符:

 {{ cars?.stylesCount }}

使用ngIf:

 <div *ngIf="cars">{{ cars.styleCount }}</div>

可能有更多的方法来处理这种情况。

关于您对 async 管道的使用,请参阅底部的更新。它也可能会导致您尝试使用它的方式出错。


此外,我建议阅读 TypeScript 类型以及 angular 和 typescript 的一般最佳实践,尤其是关于模型、接口等的使用。使用 Observables 代替 Promises 也是一个好主意。 您的代码中存在一些问题,所以这只是一个提示,但我认为这里没有详细说明这些问题的地方,也不是您问题的根源。

希望我能帮到你。


更新:

关于您对 async 管道的使用:

The async pipe subscribes to an Observable or Promise and returns the latest value it has emitted.

您在 CarObjectsarray 上使用它,顺便说一下,它不应该是一个数组。 看看the documentation for the async pipe for proper usage.