【问题标题】:Having trouble building an object with data from two different collections in AngularFirestore在 AngularFirestore 中使用来自两个不同集合的数据构建对象时遇到问题
【发布时间】:2020-06-28 21:20:58
【问题描述】:

我在 Firestore 中有一个植物集合(其中每个文档代表一种植物,并且每个植物都有自己的属性,例如 植物 ID、名称、描述、照片 URL...) 和包含用户的集合(其中每个文档代表具有自己属性的用户,包括具有他拥有的植物的植物 ID 的对象数组)

我想要实现的是,对于给定的用户,提供他拥有的植物的额外详细信息(不仅仅是 ID),这些详细信息在 Plants 集合中,所以我必须执行某种内连接操作使用用户文档中的植物 ID(检查 UserPlantView 接口声明以获得所需的输出;属性 imagedescription 将从 Plants 集合中获得)

我读到使用 rxjs 库中的 combineLatest 和 switchMap 可以做到这一点,但我无法完成它。我目前拥有的是:

plant-list.page.ts:

import 'firebase/firestore';
import { AngularFirestore } from '@angular/fire/firestore';
import { AngularFireAuth } from '@angular/fire/auth';
import { combineLatest, Observable } from 'rxjs'; 
import { switchMap } from 'rxjs/operators';

export interface Plant {
  name: string,
  pid: string,
  image: string,
  advices?: string,
  care?: string,
  clime?: string,
  curiosities?: string,
  depth?: string,
  description?: string,
  difficulty?: string,
  disease?: string,
  germinate?: string,
  irrigation?: string,
  location?: string,
  plant?: string,
  reap?: string,
  scientific?: string,
  season?: string,
  temperature?: string,
  transplant?: string,
  use?: string
}

export interface User {
  uid: string,
  name: string,
  email: string,
  plants?: [{
    id: string,
    plant_name: string,
    custom_name: string
  }]
}

export interface UserPlantView {
  uid: string,
  name: string,
  plants?: [{
    id: string,
    plant_name: string,
    custom_name: string,
    image: string,
    description: string
  }]
}

@Component({
  selector: 'app-plant-list',
  templateUrl: 'plant-list.page.html',
  styleUrls: ['plant-list.page.scss']
})
export class PlantListPage implements OnChanges {

  plantsNames: any;
  plantsList = [];
  prueba : UserPlantView;

  constructor(private AFauth: AngularFireAuth, private firestore: AngularFirestore) {
    this.getUsersPlantList();
  }

  ngOnChanges() {
    this.getUsersPlantList();
  }

  getUsersPlantList() {

    const plants : Observable<Plant[]> = this.firestore.collection<Plant>('plantas').valueChanges();
    const user : Observable<User> = this.firestore.collection('users').doc<User>(this.AFauth.auth.currentUser.uid).valueChanges();

    combineLatest(plants,user).pipe(
      switchMap(results => {
        const [plantsRes, userRes] = results;
        console.log(plantsRes);
        console.log(userRes);

        // Now I want to form a UserPlantView object using both the user document and the Plants collection...
        // ...

        return results;
      })
    ).subscribe(data => console.log(data));

  }

}

这里有控制台日志的屏幕截图,信息已从 Firestore 正确检索,但我不知道如何继续。任何帮助将不胜感激!

【问题讨论】:

  • 看起来你根本不需要使用switchMap。或者,如果你这样做了,你可以使用of() 将结果包装到一个 observable 中。

标签: typescript ionic-framework google-cloud-firestore rxjs angularfire2


【解决方案1】:

在没有 switchMap 的情况下,我终于得到了我需要的工作。代码:

在 plant-list.page.ts 中:

getPlantsList() {

    const plants : Observable<Plant[]> = this.firestore.collection<Plant>('plantas').valueChanges();
    const user : Observable<User> = this.firestore.collection('users').doc<User>(this.AFauth.auth.currentUser.uid).valueChanges();

    combineLatest(plants,user).subscribe(data => {

      this.plantUserList = {} as UserPlantView;
      this.plantUserList.uid = (<User>data[1]).uid;
      this.plantUserList.name = (<User>data[1]).name;
      if((<User>data[1]).plants) {
        this.plantUserList.plants = new Array();
        (<User>data[1]).plants.forEach(element => {
          this.plantUserList.plants.push({
              id : element.id,
              plant_name : element.plant_name,
              custom_name : element.custom_name,
              image : data[0].find(x=>x.pid == element.id).image,
              scientific: data[0].find(x=>x.pid == element.id).scientific
            })
        });
      }
    });

  }

在 plant-list.page.html:

<ng-container *ngIf="plantUserList">
<ion-item *ngFor="let item of plantUserList.plants">

  <ion-card ion-button routerLink="/tabs/tab1/{{item.id}}">
    <img alt="{{item.plant_name}}" [src]="item.image">
    <ion-card-header>
      <ion-card-subtitle>20/02/2019</ion-card-subtitle>
      <ion-card-title>{{item.custom_name}}</ion-card-title>
    </ion-card-header>

    <ion-card-content>
      <b>{{item.plant_name}}</b> ({{item.scientific}})
    </ion-card-content>
  </ion-card>
</ion-item>
</ng-container>

【讨论】:

    猜你喜欢
    • 2017-07-13
    • 2015-06-20
    • 2014-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多