Angular2 - TypeError:无法读取(Typescript)中未定义的属性“Id”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37094982/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:28:07  来源:igfitidea点击:

Angular2 - TypeError: Cannot read property 'Id' of undefined in (Typescript)

javascripttypescriptangularangular2-http

提问by Niklas

I'm getting the following error:

我收到以下错误:

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


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

thrown with:

抛出:

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


    }

}

ProductService:

产品服务:

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

Response from server:

来自服务器的响应:

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

What am I messing up?

我在捣乱什么?

回答by drew moore

In your component, you're initializing productto null, and then referencing product.Idin your template. The error occurs when Angular tries to draw your template initially, beforeyour async call returns - at which point productis still null, thus the error: Cannot read property 'Id' of null.

在您的组件中,您将初始化product为 null,然后product.Id在您的模板中进行引用。该错误发生在 Angular 最初尝试绘制模板时,异步调用返回之前- 此时product仍为空,因此出现错误:Cannot read property 'Id' of null.

The most immediate solution is to use the Elvis operator, which Angular provides for situations precisely like this. You'd use it by replacing {{ product.Id }}with {{ product?.Id }}in your template.

最直接的解决方案是使用Elvis 运算符,Angular 正好为这种情况提供了它。您可以通过在模板中替换{{ product.Id }}with{{ product?.Id }}来使用它。

That said, you're likely to run into change detection problems with this approach, and in general you'll be much better off with an approach like:

也就是说,使用这种方法可能会遇到变更检测问题,一般来说,使用以下方法会好得多:

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

You'd then use {{(product | async).Id }}in place of {{product.Id}}in your template, leveraging AsyncPipeto let angular handle the dirtywork of subscribing and updating the UI as needed for you.

然后,您{{(product | async).Id }}{{product.Id}}在您的模板中使用代替,利用AsyncPipe让 angular 根据您的需要处理订阅和更新 UI 的脏活。