使用来自 AngularFirestore 中两个不同集合的数据构建对象时遇到问题
Having trouble building an object with data from two different collections in AngularFirestore
我在 Firestore 中有一个植物集合(其中每个文档代表一种植物,每种植物都有自己的属性,例如 植物 ID、名称、描述、照片 URL...) 和一个包含用户的集合(其中每个文档代表一个具有自己属性的用户,包括一个对象数组,其中包含他拥有的植物的植物 ID)
我想要实现的是,对于给定的用户,提供他拥有的植物的额外详细信息(不仅仅是 ID),这些详细信息在 Plants 集合中,所以我必须执行某种内部操作使用用户文档中的工厂 ID 加入操作(检查 UserPlantView 接口声明以获得所需的输出;属性 image 和 description 将从植物集合)
我了解到使用 rxjs 库中的 combineLatest 和 switchMap 是可能的,但我无法完成它。我目前拥有的是:
植物-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 的情况下得到了我需要的东西。代码:
厂内-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
})
});
}
});
}
厂内-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>
我在 Firestore 中有一个植物集合(其中每个文档代表一种植物,每种植物都有自己的属性,例如 植物 ID、名称、描述、照片 URL...)
我想要实现的是,对于给定的用户,提供他拥有的植物的额外详细信息(不仅仅是 ID),这些详细信息在 Plants 集合中,所以我必须执行某种内部操作使用用户文档中的工厂 ID 加入操作(检查 UserPlantView 接口声明以获得所需的输出;属性 image 和 description 将从植物集合)
我了解到使用 rxjs 库中的 combineLatest 和 switchMap 是可能的,但我无法完成它。我目前拥有的是:
植物-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 的情况下得到了我需要的东西。代码:
厂内-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
})
});
}
});
}
厂内-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>