当前位置:  开发笔记 > 编程语言 > 正文

可观察类型错误:无法读取未定义的属性

如何解决《可观察类型错误:无法读取未定义的属性》经验,为你挑选了3个好方法。

在我的Angular 2应用程序中,我收到一个错误:

无法读取undefined的属性'title'.

这是一个非常简单的组件,只是试图在这里工作.它击中我的API控制器(奇怪地多次),它似乎在返回一个对象后点击回调.我的console.log输出了我期望的对象.这是完整的错误:

TypeError: Cannot read property 'title' of undefined
    at AbstractChangeDetector.ChangeDetector_About_0.detectChangesInRecordsInternal (eval at  (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:10897:14), :31:26)
    at AbstractChangeDetector.detectChangesInRecords (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8824:14)
    at AbstractChangeDetector.runDetectChanges (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8807:12)
    at AbstractChangeDetector._detectChangesInViewChildren (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8877:14)
    at AbstractChangeDetector.runDetectChanges (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8811:12)
    at AbstractChangeDetector._detectChangesContentChildren (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8871:14)
    at AbstractChangeDetector.runDetectChanges (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8808:12)
    at AbstractChangeDetector._detectChangesInViewChildren (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8877:14)
    at AbstractChangeDetector.runDetectChanges (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8811:12)
    at AbstractChangeDetector.detectChanges (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8796:12)

该服务(about.service.ts):

import {Http} from 'angular2/http';
import {Injectable} from 'angular2/core';
import {AboutModel} from './about.model';
import 'rxjs/add/operator/map';

@Injectable()
export class AboutService {
    constructor(private _http: Http) { }

    get() {
        return this._http.get('/api/about').map(res => {
            console.log(res.json()); // I get the error on the line above but this code is still hit.
            return res.json();
        });
    }
}

组件(about.component.ts):

import {Component, View, OnInit} from 'angular2/core';
import {AboutModel} from './about.model';
import {AboutService} from './about.service';
import {HTTP_PROVIDERS} from 'angular2/http';

@Component({
    selector: 'about',
    providers: [HTTP_PROVIDERS, AboutService],
    templateUrl: 'app/about/about.html'
})

export class About implements IAboutViewModel, OnInit {
    public about: AboutModel;

    constructor(private _aboutService: AboutService) {}

    ngOnInit() {    
        this._aboutService.get().subscribe((data: AboutModel) => {
            this.about = data;
        });
    }
}

export interface IAboutViewModel {
    about: AboutModel;
}

的index.html








Mark Rajcok.. 57

请在下次包含您的视图和型号(app/about/about.html和about.model).

如果要返回一个数组,可以使用asyncPipe,它"订阅一个Observable或Promise并返回它发出的最新值.当发出一个新值时,异步管道标记要检查组件的变化"因此视图将使用新值更新.

如果要返回基本类型(字符串,数字,布尔值),还可以使用asyncPipe.

如果你要返回一个对象,我不知道有什么方法可以使用asyncPipe,我们可以使用异步管道和安全导航操作符 ?.,如下所示:

{{(objectData$ | async)?.name}}

但这看起来有点复杂,我们必须为我们想要显示的每个对象属性重复这一点.

正如注释中提到的@pixelbits,您可以subscribe()在控制器中的observable中将包含的对象存储到组件属性中.然后在模板中使用安全导航操作符或NgIf:

service.ts

import {Injectable} from 'angular2/core';
import {Http} from 'angular2/http';
import 'rxjs/add/operator/map';  // we need to import this now

@Injectable()
export class MyService {
  constructor(private _http:Http) {}
  getArrayData() {
    return this._http.get('./data/array.json')
      .map(data => data.json());
  }
  getPrimitiveData() {
    return this._http.get('./data/primitive.txt')
      .map(data => data.text());   // note .text() here
  }
  getObjectData() {
    return this._http.get('./data/object.json')
      .map(data => data.json());
  }
}

app.ts

@Component({
  selector: 'my-app',
  template: `
    
array data using '| async':
{{item}}
primitive data using '| async': {{primitiveData$ | async}}
object data using .?: {{objectData?.name}}
object data using NgIf: {{objectData.name}}
` providers: [HTTP_PROVIDERS, MyService] }) export class AppComponent { constructor(private _myService:MyService) {} ngOnInit() { this.arrayData$ = this._myService.getArrayData(); this.primitiveData$ = this._myService.getPrimitiveData(); this._myService.getObjectData() .subscribe(data => this.objectData = data); } }

数据/ array.json

[ 1,2,3 ]

数据/ primitive.json

Greetings SO friends!

数据/ object.json

{ "name": "Mark" }

输出:

array data using '| async':
1
2
3
primitive data using '| async': Greetings SO friends!
object data using .?: Mark
object data using NgIf: Mark

Plunker



1> Mark Rajcok..:

请在下次包含您的视图和型号(app/about/about.html和about.model).

如果要返回一个数组,可以使用asyncPipe,它"订阅一个Observable或Promise并返回它发出的最新值.当发出一个新值时,异步管道标记要检查组件的变化"因此视图将使用新值更新.

如果要返回基本类型(字符串,数字,布尔值),还可以使用asyncPipe.

如果你要返回一个对象,我不知道有什么方法可以使用asyncPipe,我们可以使用异步管道和安全导航操作符 ?.,如下所示:

{{(objectData$ | async)?.name}}

但这看起来有点复杂,我们必须为我们想要显示的每个对象属性重复这一点.

正如注释中提到的@pixelbits,您可以subscribe()在控制器中的observable中将包含的对象存储到组件属性中.然后在模板中使用安全导航操作符或NgIf:

service.ts

import {Injectable} from 'angular2/core';
import {Http} from 'angular2/http';
import 'rxjs/add/operator/map';  // we need to import this now

@Injectable()
export class MyService {
  constructor(private _http:Http) {}
  getArrayData() {
    return this._http.get('./data/array.json')
      .map(data => data.json());
  }
  getPrimitiveData() {
    return this._http.get('./data/primitive.txt')
      .map(data => data.text());   // note .text() here
  }
  getObjectData() {
    return this._http.get('./data/object.json')
      .map(data => data.json());
  }
}

app.ts

@Component({
  selector: 'my-app',
  template: `
    
array data using '| async':
{{item}}
primitive data using '| async': {{primitiveData$ | async}}
object data using .?: {{objectData?.name}}
object data using NgIf: {{objectData.name}}
` providers: [HTTP_PROVIDERS, MyService] }) export class AppComponent { constructor(private _myService:MyService) {} ngOnInit() { this.arrayData$ = this._myService.getArrayData(); this.primitiveData$ = this._myService.getPrimitiveData(); this._myService.getObjectData() .subscribe(data => this.objectData = data); } }

数据/ array.json

[ 1,2,3 ]

数据/ primitive.json

Greetings SO friends!

数据/ object.json

{ "name": "Mark" }

输出:

array data using '| async':
1
2
3
primitive data using '| async': Greetings SO friends!
object data using .?: Mark
object data using NgIf: Mark

Plunker



2> TheKojuEffec..:

它看起来像你about.title在视图中引用,about.htmlabout只有在http请求完成后才会实例化变量.为避免此错误,您可以about.html使用

...



3> 小智..:

以前的答案是正确的.在模板中使用变量之前,您需要检查变量是否已定义.使用HTTP请求需要时间来定义它.使用*ngIf来检查.示例是通过https://angular.io/docs/ts/latest/tutorial/toh-pt5.html从角度提供的 ,示例是http://plnkr.co/edit/?p=preview

{{hero.name}} details!

你可以查看app/hero-detail.component [ts和html]

推荐阅读
乐韵答题
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有