I am new to Angular2 integration with Firebase so please forgive my naivety.
I'm using the AngularFire2 plugin to connect with my Firebase db and have been following their GitHub docs as such.
Up until now when I retrieve a FirebaseObjectObservable
, I display it in my HTML using the async
pipe described in the docs:
To get the object in realtime, create an object binding as a property of your component or service. Then in your template, you can use the async pipe to unwrap the binding.
HTML:
<ion-list *ngFor="let member of _tripMembers">
<ion-item>
<ion-avatar item-left>
<img src="{{ (member | async)?.photoUrl }}">
</ion-avatar>
<ion-label>{{ (member | async)?.firstName }} {{ (member | async)?.lastName }}</ion-label>
<ion-checkbox color="positive" [(ngModel)]="member.checked" (click)="toggleClicked(member, !member.checked)" item-right></ion-checkbox>
</ion-item>
</ion-list>
When calling the toggleClicked
function when the ion-checkbox
is clicked, the first parameter I want to pass in is the member's key and not the full member (as is shown). This is described in the here in the docs as just using member.$key
but that returns undefined
.
I can display the key again by using the async
pipe using:(member | async).$key
However, I cannot do this within an arguments listings as you can't have pipes there.
EDIT:
_tripMembers
is just a basic JS array that holds FirebaseObjectObservable
's. Since a member
is an individual item in firebase I would have thought it would be a FirebaseObjectObservable
and NOT a FirebaseListObservable
. The example in the documentation is that if you are getting a LIST of items, you use a FirebaseListObservable
. You would use a FirebaseObjectObservable
if you are only getting individual items (which is what I'm doing),
getUserWithID(userID): FirebaseObjectObservable<any> {
return this.af.database.object('users/' + userID);
}
setTripMembers(): void {
allUsers.forEach((user) => {
tripMembersID.forEach((member) => {
if (user.$key === member) {
tripMembers.push(getUserWithID(user.$key));
}
});
});
let modal = this.modalCtrl.create(LocationModal, {
name: name,
members: tripMembers
});
}
Is this wrong? Should getting an individual item be a FirebaseListObservable
? If yes, can someone then please explain as in what scenario we a FirebaseObjectObservable
would be used as I don't feel the docs explain it well.
Or is it that _tripMembers
has to be a FirebaseListObservable<FirebaseObjectObservable>
?
Don't use async everywhere. Just use it in the ngFor on your collection.
<ion-list *ngFor="let member of _tripMembers | async">
EDIT:
You'll want to "unwrap" the observables on the code side before they make it to your template, and without passing them around or pushing them into your array.
Take a look at this comment which helped me out when starting with AngularFire.
this.af.database.object('path')
is meant to be consumed & automagically unwrapped by the template. To get the data out of it on the code side requires you to subscribe to it. But just subscribing will leave the observable in a live state. Use thetake
operator to get the data and close the observable.FirebaseObjectObservable
&FirebaseListObservable
are simple ways to get your data showing up in a template. But once you start manipulating them you need to do more work with the Observables to create POJOs/Arrays which will end up as the model for your views.It might end up looking something like: