Estou tentando entender como usar Observáveis no Angular 2. Tenho este serviço:
import {Injectable, EventEmitter, ViewChild} from '@angular/core';
import {Observable} from "rxjs/Observable";
import {Subject} from "rxjs/Subject";
import {BehaviorSubject} from "rxjs/Rx";
import {Availabilities} from './availabilities-interface'
@Injectable()
export class AppointmentChoiceStore {
public _appointmentChoices: BehaviorSubject<Availabilities> = new BehaviorSubject<Availabilities>({"availabilities": [''], "length": 0})
constructor() {}
getAppointments() {
return this.asObservable(this._appointmentChoices)
}
asObservable(subject: Subject<any>) {
return new Observable(fn => subject.subscribe(fn));
}
}
Este BehaviorSubject recebe novos valores de outro serviço:
that._appointmentChoiceStore._appointmentChoices.next(parseObject)
Eu me inscrevo na forma de um observável no componente que desejo exibi-lo em:
import {Component, OnInit, AfterViewInit} from '@angular/core'
import {AppointmentChoiceStore} from '../shared/appointment-choice-service'
import {Observable} from 'rxjs/Observable'
import {Subject} from 'rxjs/Subject'
import {BehaviorSubject} from "rxjs/Rx";
import {Availabilities} from '../shared/availabilities-interface'
declare const moment: any
@Component({
selector: 'my-appointment-choice',
template: require('./appointmentchoice-template.html'),
styles: [require('./appointmentchoice-style.css')],
pipes: [CustomPipe]
})
export class AppointmentChoiceComponent implements OnInit, AfterViewInit {
private _nextFourAppointments: Observable<string[]>
constructor(private _appointmentChoiceStore: AppointmentChoiceStore) {
this._appointmentChoiceStore.getAppointments().subscribe(function(value) {
this._nextFourAppointments = value
})
}
}
E a tentativa de exibir na visualização como:
<li *ngFor="#appointment of _nextFourAppointments.availabilities | async">
<div class="text-left appointment-flex">{{appointment | date: 'EEE' | uppercase}}
No entanto, as disponibilidades ainda não são uma propriedade do objeto observável, portanto, ocorre um erro, mesmo que eu tenha definido isso na interface de disponibilidades como:
export interface Availabilities {
"availabilities": string[],
"length": number
}
Como posso exibir uma matriz de forma assíncrona de um objeto observável com o pipe assíncrono e * ngFor? A mensagem de erro que recebo é:
browser_adapter.js:77 ORIGINAL EXCEPTION: TypeError: Cannot read property 'availabilties' of undefined
typescript
angular
rxjs
observable
C. Kearns
fonte
fonte
*ngFor="let appointment of _nextFourAppointments.availabilities | async">
availabilties
enquanto deveria haveravailabilities
Respostas:
Aqui está um exemplo
fonte
public _appointmentChoices: Subject<any> = new Subject() getAppointments() { return this._appointmentChoices.map(object=>object.availabilities).subscribe() }
no controlador quando eu configuro igual, recebo o erro:,browser_adapter.js:77Error: Invalid argument '[object Object]' for pipe 'AsyncPipe'
como faço para transformar o assunto em um observável?public _appointmentChoices: Subject<any> = new Subject() getAppointments() { return (this._appointmentChoices.map(object=>object.availabilities).asObservable()) } }
isso me dá o erroproperty asObservable does not exist on type observable
:, mas _appointmentChoices é umSubject
?Quem nunca também tropeça neste post.
Eu acredito que é a maneira correta:
fonte
Acho que o que você está procurando é isso
fonte
Se você não tem um array, mas está tentando usar seu observável como um array, embora seja um stream de objetos, isso não funcionará nativamente. Mostro como consertar isso a seguir, supondo que você só se preocupe em adicionar objetos ao observável, não em excluí-los.
Se você estiver tentando usar um observável cuja fonte seja do tipo BehaviorSubject, altere-o para ReplaySubject e em seu componente assine-o assim:
Componente
Html
fonte
scan
operadora, você pode usar.pipe(toArray())
Subject
é não ligarcomplete()
. O acumulador nunca será executado.