Angular 2 - 无法读取 属性 未定义的“...”

Angular 2 - Cannot read property '...' of undefined

对 Angular 很陌生。我检查了类似的问题,但他们要么深入细节,要么我就是不明白解决方案。

实际错误: "Cannot read property 'idPlanet' of undefined at Object.eval [as updateRenderer] (PlanetComponent.html:11)"

问题: planetDetail.idPlanet 很可能是未定义的?

嫌疑人: getPlanetDetail()

planet.component.html:

<div class="col-sm-9">
  ID: {{ planetDetail.idPlanet }}
</div>

planet.component.ts:

import {
  Component,
  OnInit
} from '@angular/core';

import { Planet }               from './planet';
import { PlanetService }        from './planet.service';

@Component({
  selector: 'planets',
  templateUrl: './planet.component.html'
})
export class PlanetComponent implements OnInit {

    private planets: Planet[];
    private planetDetail: Planet;
    constructor(
        private planetService: PlanetService
    ) {}

    public ngOnInit(): void {
      this.getPlanetDetail();
      this.getPlanets();
    }

    public getPlanets() {
      this.planetService.getPlanets()
          .subscribe(
              (planets) => this.planets = planets
          );
    }

    public getPlanetDetail() {
      this.planetService.getPlanetDetail()
          .subscribe(
              (planets) => this.planetDetail = planets
          );
    }

}

planet.service.ts:

import { Injectable }    from '@angular/core';
import { Headers, Http, Response } from '@angular/http';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

import { Planet } from './planet';

@Injectable()
export class PlanetService {

    private planetsUrl = 'http://localhost/index.php/api/planet/';  // URL to web api

    // Injecting the http client into the service
    constructor(private http: Http) {}

    public getPlanets(): Observable<Planet[]> {
        return this.http.get(this.planetsUrl + 'planets/id_sol/1')
            .map(this.parseData)
            .catch(this.handleError);
    }

    public getPlanetDetail(): Observable<Planet> {
      return this.http.get(this.planetsUrl + 'planet/id_planet/1')
          .map(this.parseData)
          .catch(this.handleError);
    }

    private parseData(res: Response) {
        let body = res.json();

        if (body instanceof Array) {
            return body || [];
        } else {
            return body.post || {};
        }
    }

    private handleError(error: any): Promise<any> {
        console.error('An error occurred', error); // for demo purposes only
        return Promise.reject(error.message || error);
    }
}

老实说,我不知所措,我尝试从 getPlanets() 构建我的 getPlanetDetail() 方法,它工作正常。我应该使用承诺吗?

我很难确定我可以将 console.log() 放在何处进行调试。我正在使用 angular-来自 Github.

的入门套件

感谢您的宝贵时间。

编辑 1:api 输出 {"idPlanet":"1","name":"Earth"}

由于请求是异步的,有时页面加载时不会从服务器获取值,因此,planetDetail 未定义。为了避免这种情况,您可以使用添加 '?'在 planetDetail 和 idPlanet 之间。仅当它具有值

时才打印

ID: {{ planetDetail?.idPlanet }}

如果要打印结果或错误 public getPlanetDetail() { this.planetService.getPlanetDetail() .subscribe( (planets) => { console.log(planets); this.planetDetail = planets }, error => {console.log(error);} ); }

我的朋友调试如果你的'planetDetail'被填充,只需在'subscribe'方法中添加'console.log (planetDetail)'。按照下面的示例。

public getPlanetDetail() {
  this.planetService.getPlanetDetail()
      .subscribe(
          (planets) => this.planetDetail = planets
      );
}

public getPlanetDetail() {
  this.planetService.getPlanetDetail()
      .subscribe(
          (planets) => this.planetDetail = planets, (err) => (err), () => console.log(this.palnetDetail)
      );
}

关于 subscribe() 的更多信息

subscribe(function(response) {
  console.log("Success Response" + response)
},
  function(error) {
  console.log("Error happened" + error)
},
  function() {
  console.log("the subscription is completed")
}); 

由于您的回答是 {"idPlanet":"1","name":"Earth"},请尝试以下操作:

public getPlanetDetail(): Observable<Planet> {
    return this.http.get(this.planetsUrl + 'planet/id_planet/1')
        .map(res => res.json())
        .catch(this.handleError);
}