Возникли проблемы при создании объекта с данными из двух разных коллекций в AngularFirestore - PullRequest
0 голосов
/ 17 марта 2020

У меня в Firestore есть коллекция с растениями (где каждый документ представляет растение, и у каждого растения есть свои атрибуты, такие как идентификатор растения , название, описание, URL фотографии ...) Screenshot 1 и коллекция с пользователями (где каждый документ представляет пользователя со своими собственными атрибутами, включая массив объектов с идентификаторами растений принадлежащих ему растений)

Screenshot 2

Что я хочу добиться, так это дать конкретному пользователю дополнительную информацию о растениях, которыми он владеет (не только идентификатор), эти сведения находятся в коллекции «Растения», поэтому я должен выполнить какое-то операции внутреннего соединения с использованием идентификатора установки в пользовательском документе (проверьте объявление интерфейса UserPlantView для желаемого результата; атрибуты image и description будут получены из коллекции Plants)

Я читал, что это возможно с использованием combLatest и switchMap из библиотеки rx js, но я не могу этого сделать sh. Сейчас у меня есть:

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, но я не знаю, как продолжать идти. Любая помощь будет высоко ценится!

Here you have a screenshot

1 Ответ

0 голосов
/ 20 марта 2020

Я наконец получил то, что мне нужно было работать без switchMap. Код:

На заводе-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
            })
        });
      }
    });

  }

На заводе-списке.страница 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>
...