简体   繁体   English

Angular2服务返回未定义

[英]Angular2 Service Returns Undefined

For some reason my services aren't working. 由于某种原因,我的服务无法正常工作。 I've been lurking SO for two days trying to find similar questions, but they don't fit my problem. 我一直在潜伏两天,试图找到类似的问题,但是它们不适合我的问题。

Service.ts: 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);
  }

}

These are my '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;
}

My component: 我的组件:

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

}

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

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

Error Output: 错误输出:

EXCEPTION: Error in ./EdmundsSearchResultComponent class 
EdmundsSearchResultComponent - inline template:0:0 caused by: 
Cannot read    property 'stylesCount' of undefined
  1. CarObject was designed to match the API Response, so it could be okay to remove the array brackets ( [] ) CarObject旨在匹配API响应,因此可以删除数组括号([])
  2. I don't know why this won't display the object data on my template despite closely following the Tour Of Heroes HTTP/Services tutorial. 我不知道为什么尽管严格遵循Tour Of Heroes HTTP / Services教程,但这样在我的模板上不显示对象数据。

What I am trying to do is make an HTTP request from variable 'styleurl' (which I see is successfully made by checking the 'Network' tab in chrome dev tools.) Using this API Response, I want my CarObject to 'consume' the json response, and be available to my component/template. 我想做的是从变量'styleurl'发出HTTP请求(我发现通过检查chrome dev工具中的'Network'标签成功完成了。)使用此API响应,我希望我的CarObject“消费” json响应,并且可用于我的组件/模板。

In your component you're reserving your car property, but you don't initialize it, so it remains undefined . 在组件中,您保留了car属性,但未初始化它,因此它保持undefined

At the time your HTML renders the promise isn't fulfilled yet, your car is still undefined but you try to access a property from it. 当您的HTML呈现承诺尚未实现时,您的car仍未undefined但是您尝试从中访问属性。

A couple solutions: 几个解决方案:

preset it : 预设

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

use the elvis operator in your template : 在模板中使用elvis运算符

 {{ cars?.stylesCount }}

use ngIf : 使用ngIf

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

There are probably a couple of more ways to handle this case. 可能还有其他几种方法可以处理这种情况。

See my update at the bottom regarding your usage of the async pipe. 有关使用async管道的信息,请参阅底部的我的更新。 It probably leads to errors as well in the way you're trying to use it. 尝试使用它的方式也可能会导致错误。


Besides, i would suggest reading up on TypeScript types as well as general best practices for angular and typescript especially regarding the usage of models, interfaces and such. 此外,我建议阅读TypeScript类型以及有关angular和Typescript的一般最佳实践,尤其是有关模型,接口等的用法。 Also using Observables would be a good idea instead of Promises. 另外,使用Observables代替Promises是个好主意。 There are some issues in your code, so this is just a hint, but elaborating on them has no place here i think and aren't the source of your problem. 您的代码中存在一些问题,因此这仅是一个提示,但是我认为在这里对其进行详细说明并不重要,也不是问题的根源。

Hope i could help. 希望我能帮上忙。


Update: 更新:

About your usage of the async pipe: 关于async管道的用法:

The async pipe subscribes to an Observable or Promise and returns the latest value it has emitted. 异步管道订阅Observable或Promise并返回其发出的最新值。

You use it on an array of CarObjects which btw shouldn't be an array. 您在CarObjects array上使用它,但btw不应为数组。 Take a look at the documentation for the async pipe for proper usage. 查看异步管道的文档以正确使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM