我试图从角度的服务中获取AngularFirestoreCollection。 AngularFirestoreCollection在可观察订阅中异步初始化。当我尝试从组件中获取集合时,我收到错误,因为它未定义。
以下是我服务的代码:
collapse
这是我的组件的代码:
fokosCollection: AngularFirestoreCollection<Foko>;
myFokos: Observable<Foko[]>;
constructor(auth: AuthService, public afs: AngularFirestore) {
this.myFokos = auth.user$.switchMap(user => {
if (user) {
this.fokosCollection = afs.collection<Foko>('users/' + user.uid + '/fokos');
return this.fokosCollection.valueChanges();
}
});
}
我尝试创建一个在初始化Collection时通知组件的Subject。当我直接导航到此组件时,这有效。但是,如果我从另一个组件导航到此组件,则从不调用主题订阅(因为主题发出集合时订阅不存在)。
以下是我的尝试:
this.myListService.fokosCollection.doc(codeInput).valueChanges().take(1).subscribe(foko => {
getData(foko)
});
我将组件的代码更改为:
fokosCollection: AngularFirestoreCollection<Foko>;
fokosCollectionSubject = new Subject<AngularFirestoreCollection<Foko>>();
myFokos: Observable<Foko[]>;
constructor(auth: AuthService, public afs: AngularFirestore) {
this.myFokos = auth.user$.switchMap(user => {
if (user) {
this.fokosCollection = afs.collection<Foko>('users/' + user.uid + '/fokos');
this.fokosCollectionSubject.next(this.fokosCollection);
...
我可以尝试获取Collection,如果它抛出错误,请订阅Subject。但是,我认为这不是好的代码。那么,在Angular中使用异步数据进行去除的最佳做法是什么?
答案 0 :(得分:1)
在您的switchMap
中,如果用户是假的,则您不会返回值。你应该归还一些东西。使用filter
运算符可以防止出现这种情况。
由于您想知道何时初始化fokosCollection
,我建议您将其作为可观察对象公开。
fokosCollection: Observable<AngularFirestoreCollection<Foko>>;
myFokos: Observable<Foko[]>;
constructor(auth: AuthService, public afs: AngularFirestore) {
this.fokosCollection = auth.user$
.filter(x => x != null)
.map(user => afs.collection<Foko>('users/' + user.uid + '/fokos'))
.shareReplay(1);
this.myFokos = this.fokosCollection.switchMap(x => x.valueChanges());
}
我添加了shareReplay(1)
来共享单个基础订阅,并将最后一个值重播给新订阅者。你可能会或可能不想在你的场景中使用它,但我发现在暴露可能有多个订阅的observable时我通常会想要它。
然后在你的组件中:
this.myListService.fokosCollection.switchMap(x => x.doc(codeInput).valueChanges()).take(1).subscribe(foko => {
getData(foko)
});