How can I build an Observable that's limited to a single doc?
This builds an Observable when querying for any number of docs:
foo.component.ts
import { AngularFirestore } from '@angular/fire/firestore';
import { Observable } from 'rxjs';
...
export class FooComponent implements OnInit {
...
docs: Observable<any[]>;
constructor(private db: AngularFirestore) {
this.docs = db.collection('myCollection', ref => ref.where('name', '==', 'foobar')).valueChanges();
}
foo.component.html
<div *ngFor="let doc of docs | async">
{{ doc.name }}, {{ doc.address }}
</div>
How can I do this when I know there's only 1 doc that'll be returned? I just won't know the doc ID in advance.
Something like the code above, except with just doc: Observable<any>;
instead of docs: Observable<any[]>;
so I don't have to use an *ngFor
loop over the results?
I've tried
this.doc = db.collection('myCollection', ref => ref.where('name', '==', 'foobar').limit(1)).valueChanges();
Working stackblitz: https://stackblitz.com/edit/angular-v7yff2
Based on https://stackblitz.com/edit/angular-lymeyp, you just need to do the following in the component
crazinessToObserveASingleDoc() {
this.singleDoc = this.db.collection('users', ref => ref.where('email', '==', this.email)).valueChanges().pipe(
tap(docs => console.log('docs', docs)),
map(val => val.length > 0 ? val[0] : null)
)
}
and in the template
<div>
<span class="title">Document with email <span class="italics">{{ email }}</span>:</span>
<div *ngIf="singleDoc | async as doc">{{ doc.name }}, {{ doc.email }}</div>
</div>
Previous solution
Don't do take(1)
as suggested in some comments: it completes the observable and then you will stop listening for changes (why using a realtime database then?). Also, you will still receive an array of results...
If you don't know the id of the document, what you need to do is this:
const doc: Observable<any | null> =
db.collection('myCollection', ref => ref.where('name', '==', 'foobar'))
.valueChanges()
.pipe(map(val => val.length > 0 : val[0] : null));
where map if from rxjs/operators
.