que observables example ejemplo angular observable rxjs

angular - observables - Error de tipo observable: no se puede leer la propiedad de indefinido



subscribe angular 4 (3)

Incluya su vista y modelo la próxima vez (app / about / about.html y about.model).

Si está devolviendo una matriz , puede usar el asyncPipe , que "se suscribe a un Observable o Promesa y devuelve el último valor que ha emitido. Cuando se emite un nuevo valor, la tubería asíncrona marca el componente para verificar los cambios". la vista se actualizará con el nuevo valor.

Si devuelve un tipo primitivo (cadena, número, booleano), también puede usar asyncPipe.

Si está devolviendo un objeto , no conozco ninguna forma de usar asyncPipe , ¿podríamos usar la tubería asíncrona, junto con el operador de navegación segura ?. como sigue:

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

Pero eso parece un poco complicado, y tendríamos que repetir eso para cada propiedad de objeto que queramos mostrar.

Como @pixelbits mencionó en un comentario, puede subscribe() a lo observable en el controlador y almacenar el objeto contenido en una propiedad de componente. Luego use el operador de navegación segura o NgIf en la plantilla:

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: ` <div>array data using ''| async'': <div *ngFor="let item of arrayData$ | async">{{item}}</div> </div> <div>primitive data using ''| async'': {{primitiveData$ | async}}</div> <div>object data using .?: {{objectData?.name}}</div> <div *ngIf="objectData">object data using NgIf: {{objectData.name}}</div>` 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); } }

data / array.json

[ 1,2,3 ]

data / primitive.json

Greetings SO friends!

data / object.json

{ "name": "Mark" }

Salida:

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

Plunker

En mi aplicación Angular 2, aparece un error:

No se puede leer la propiedad ''título'' de indefinido.

Este es un componente muy simple, solo tratando de obtener un mínimo para trabajar aquí. Golpea mi controlador API (curiosamente varias veces), y parece golpear la devolución de llamada después de que se devuelve un objeto. Mi console.log genera el objeto que esperaría. Aquí está el error completo:

TypeError: Cannot read property ''title'' of undefined at AbstractChangeDetector.ChangeDetector_About_0.detectChangesInRecordsInternal (eval at <anonymous> (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:10897:14), <anonymous>: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)

El servicio (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 <AboutModel>res.json(); }); } }

El componente (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

<script src="~/lib/systemjs/dist/system.src.js"></script> <script src="~/lib/angular2/bundles/router.js"></script> <script src="~/lib/angular2/bundles/http.js"></script> <script src="~/lib/angular2/bundles/angular2-polyfills.js"></script> <script src="~/lib/angular2/bundles/angular2.dev.js"></script> <script src="~/lib/es6-shim/es6-shim.js"></script> <script> System.config({ packages: { app: { format: ''register'', defaultExtension: ''js'' }, rxjs: { defaultExtension: ''js'' } }, map: { rxjs: "lib/rxjs" } }); System.import(''app/boot'') .then(null, console.error.bind(console)); </script>


La respuesta anterior es correcta. Debe verificar si la variable está definida antes de usarla en su plantilla. Usando la solicitud HTTP, necesita tiempo para definirla. use * ngIf para verificar. El ejemplo se proporciona desde angular con https://angular.io/docs/ts/latest/tutorial/toh-pt5.html y el ejemplo es http://plnkr.co/edit/?p=preview

<div *ngIf="hero"> <h2>{{hero.name}} details!</h2> <div>

Puede consultar app / hero-detail.component [ts y html]


Parece que se ha referido a about.title en la vista about.html pero la variable about solo se instancia una vez que se completa la solicitud http . Para evitar este error, puede envolver about.html con <div *ngIf="about"> ... </div>