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
Angular2 - TypeError: Cannot read property 'Id' of undefined in (Typescript)
提问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 product
to null, and then referencing product.Id
in your template. The error occurs when Angular tries to draw your template initially, beforeyour async call returns - at which point product
is 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 AsyncPipe
to let angular handle the dirtywork of subscribing and updating the UI as needed for you.
然后,您{{(product | async).Id }}
将{{product.Id}}
在您的模板中使用代替,利用AsyncPipe
让 angular 根据您的需要处理订阅和更新 UI 的脏活。