【问题标题】:Angular2 Service Returns UndefinedAngular2 服务返回未定义
【发布时间】:2017-02-07 16:23:05
【问题描述】:

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

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);
  }

}

这些是我的“模型”:

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: {{汽车.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/服务教程,但它不会在我的模板上显示对象数据。

我想要做的是从变量“styleurl”发出一个 HTTP 请求(我看到这是通过检查 chrome 开发工具中的“网络”选项卡成功发出的。)使用这个 API 响应,我希望我的 CarObject '消费 json 响应,并可供我的组件/模板使用。

【问题讨论】:

  • 虽然问题不一样,但两个问题的答案都是一样的。检查我在上面问题中的答案。
  • @SabbirRahman 我看了你的回答,还是不明白该怎么做。请更明确。
  • 您正在尝试访问 cars 对象的 stylesCount 属性,该属性在模板首次尝试访问时未定义。要解决这个问题,您只需在声明时为汽车对象分配一个空对象。 declare cars: any = {}。如果您不想使用 any,则必须分配默认对象而不是 {}。
  • @SabbirRahman 我已将cars: CarObject; 替换为declare cars: any = {} 并收到以下错误(15,3): declare modifier cannot appear on a class element.)

标签: javascript json angular typescript angular2-services


【解决方案1】:

在您的组件中,您保留了 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 管道的使用:

异步管道订阅 Observable 或 Promise 并返回它发出的最新值。

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

【讨论】:

  • 嘿!非常感谢您的回复,但是,我仍然很困扰。是的,我不介意转换为 observables,我现在就这样做 -> 转换非常简单。但是,您说我的代码中存在问题-这是我要解决的问题-我希望您能详细说明一下,因为我是 Angular2 的新手,并且很想纠正我做错的事情!
  • 好吧,我的意思是你如何使用响应并将其声明为CarsObject 的数组,而不仅仅是一个对象。在您的汽车模型中使用构造函数将是一种正确的方法,因此您的服务会创建汽车的实例并将它们传递回您的视图。异步管道绑定到 Promise 或 Observable,而不是您类型的数组或对象。再说一遍,这只是关于最佳实践、结构/可维护性。据我所知,您最初发布的错误消息与它无关。如果您遵循其中一个示例会发生什么?
  • 我使用&lt;ng-container *ngIf="cars"&gt;{{ cars.styleCount }}&lt;/ng-container&gt; 无济于事。该应用程序不会从 json 响应中加载我的数据。顺便说一句,我刚刚将我的 Promises 转换为 observable -> 一分钟内检查编辑代码
  • 没有 CarsObject 怎么办?如果它是 TS(或 js)原生的,则只使用一个对象
  • 我更新了关于异步管道的帖子。 “应用程序不会从 json 响应中加载我的数据”是什么意思?你有任何错误吗?如果您在组件中分配console.log(this.cars) 之后立即执行它,您的输出是什么?你能用elvis 运算符试试吗?我不确定ng-container 内部是否需要一个 html 元素,我更新了我的帖子以确保安全,因为我现在没有时间测试它。
猜你喜欢
  • 1970-01-01
  • 2016-11-04
  • 2018-10-25
  • 1970-01-01
  • 1970-01-01
  • 2018-03-06
  • 2016-03-20
  • 1970-01-01
相关资源
最近更新 更多