7

次のエラーが表示されます。

angular2.dev.js:23925 EXCEPTION: TypeError: Cannot read property 'Id' of null in [


{{ product.Id }}
 in ProductEditComponent@0:68]

でスロー:

//Product-edit.component.ts:

import {Component } from 'angular2/core';
import { IProduct } from './product'
import { ProductService } from './product.service'
import { RouteParams } from 'angular2/router';
@Component({
  template:`<div class="wrapper wrapper-content animated fadeInRight ecommerce"> 
              {{ product.Id }}
            </div>`, 
})
export class ProductEditComponent{
    product: IProduct = null;
    errorMessage: string;
    constructor(private _routeParams: RouteParams, private _productService: ProductService){

    }

    ngOnInit(): void {
        this._productService.getProduct(this._routeParams.get('id'))
            .subscribe(
                product => this.product = product,
                error => this.errorMessage = <any>error);


    }

}

製品サービス:

getProduct(id: string): Observable<IProduct> {
    return this._http.get(this._baseUrl + this._getProductUrl + '/' + id)
        .map((response: Response) => <IProduct>response.json())
        .do(data => console.log("All: " + JSON.stringify(data)))
        .catch(this.handleError);
}

サーバーからの応答:

{"Id":"34d4efcy6","ExternalId":null,"UserId":"testing","ProductProvider":null,"Title":"Flaska vin","Desc":null,"MinDeliveryTime":null,"MaxDeliveryTime":null,"FreightCost":null,"Brand":null}

私は何を台無しにしていますか?

4

1 に答える 1

27

コンポーネントでは、productnull に初期化してからproduct.Id、テンプレートで参照しています。このエラーは、非同期呼び出しが返される前に、Angular が最初にテンプレートを描画しようとしたときに発生します。その時点productではまだ null であるため、エラー: Cannot read property 'Id' of null.

最も直接的な解決策は、まさにこのような状況に対して Angular が提供するElvis operatorを使用することです。テンプレートで に置き換えて使用{{ product.Id }}します。{{ product?.Id }}

とはいえ、このアプローチでは変更検出の問題が発生する可能性が高く、一般的には次のようなアプローチの方がはるかに優れています。

export class ProductEditComponent{
  product: Observable<IProduct>; //product is an Observable
  errorMessage: string;
  constructor(private _routeParams: RouteParams, private _productService: ProductService){
     //product is always defined because you instantiate it in the ctor
     this._productService.getProduct(this._routeParams.get('id'));
  }

次に、テンプレート{{(product | async).Id }}の代わりに使用し、Angular が必要に応じてサブスクライブして UI を更新するという面倒な作業を処理できるようにします。{{product.Id}}AsyncPipe

于 2016-05-08T01:07:09.687 に答える