No idea how to properly "ask" this. I think in MySQL it was called "Joining" or something like that.
I have a collection called "Photos". I want the ability to add "Comments" to a photo. Those "Comments" will be stored in another collection. The structure for a comment his like this:
I have an Angular page that already is displaying info about a Photo. Now I want to display the comments for that photo. How can I pull only the comments that belong to that photo??
Also, I want this to be asyc because I will have the ability to add a new comment "on the fly".
Thank you very much!
You can just query your comments
collection like so:
...
constructor(private afs: AngularFirestore) {
afs.collection('comments', ref => ref.where('photoId','==', this.idOfPhotoYouAreDisplaying)).valueChanges()
}
...
if you want to check for null
in the template you can assign the result to a variable (eg comments
):
comments: Comment[];
comments$: Observable<Comment[]>;
constructor(private db: AngularFirestore) {
this.comments$ = this.db.collection(config.collection_comments, ref => ref.where('photoId', '==', this.photoId))
.snapshotChanges()
.pipe(
map(actions => {
return actions.map(a => {
const data = a.payload.doc.data() as Comment;
const id = a.payload.doc.id;
return { id, ...data };
});
}));
}
ngOnInit() {
this.comments$.subscribe(c => this.comments == c);
}
Now in your template you can check on comments
:
<div *ngIf="comments">
<div *ngFor="let comment of comments">
...
</div>
</div>
Note 1:
You don't have to assign it to a variable. You can check with the async
pipe in ngIf
, but when you loop over your comments, again with async
you create a second subscription, which will cause you're query to execute twice.
Note 2:
Using the async
pipe handles the unsubscription of your observable. When subscribing in the component you need to handle this yourself. (Multiple ways to do this)