简体   繁体   中英

How can I format and display Firestore data returned from AngularFire?

I have a simple list of teams, first I had each team in one firebase document, and when querying the collection it was straightforward to display them in HTML with *ngFor . Very simple example:

<ion-card *ngFor="let t of (team|async)" >
  <ion-card-header>
    <ion-card-title>name: {{t.name}} </ion-card-title>
      {{t.pic}}
      score = {{t.score}}
  </ion-card-header>
</ion-card>

Then, I decided to test putting all the teams in just one Firebase document using the map type (json object). But now the *ngFor won't work. (I get the essence of why, but can't solve it):

This is the DB doc:

在此处输入图片说明

Say this is the new query:

this.teams= this._db.collection('teams').doc("allteams").valueChanges();

Then I tried making the response an array: (because otherwise *ngFor would show errors)

this.team= this.teams.pipe(map((res: Response) => {return [res]}));

and after doing so, in HTML I can only access one single value as of example:

<ion-card *ngFor="let t of (team|async)" >
  <ion-card-header>
    <ion-card-title>name: {{t.team1.name}} </ion-card-title>
  </ion-card-header>
</ion-card>

but I really cannot get to show as did before:

<ion-card *ngFor="let t of (team|async)" >
  <ion-card-header>
    <ion-card-title>name: {{t.name}} </ion-card-title>
      {{t.pic}}
      score = {{t.score}}
  </ion-card-header>
</ion-card>

I understand that the response is only one array, but can't transform it into something that works.

I've also tried something like:

this.team= this.teams.pipe(map((res: Response)=> {for(let r in res){return r}}));

but this will only console.log: team1, team2, team3 . All the other data is not there.

Thanks sincerely for the help! :)

Your last attempt was pretty close, but you're effectively only returning the key in this case (which is the behavior you observe).

Since AngularFire just returns the raw document value when you call valueChanges on a document, you can manipulate it like you would the object directly. Since you want to return the value for a given key, so you just need to pull it off the object.

Try this:

this.team = this.teams.pipe(map(res => {
  return Object.keys(res).map(x => res[x]);
}));

This code maps across all the keys on the object, and returns an array of all of the values of those keys. The Angular / Ionic template should be able to deal with this in the way you are expecting.

Side note: I've switched to Object.keys as tslint likes to throw an error for an unfiltered for x in obj .

I'm also not quite sure what a Response is here so I've omitted the type for clarity -- this code isn't really type dependent.

The above code doesn't preserve the key, of course. If you want to do that, you can:

this.team = this.teams.pipe(map(res => {
  return Object.keys(res).map(x => {
    const output = res[x];
    output._key = x;
    return output;
  });
}));

Just make sure that you use a property (in this case _key ) that won't exist on your objects, or it will be overwritten :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM