我正在Angular 6和angularfire2中做一个Web应用程序。在我的服务中,我有一个Observable数组,我想对其进行过滤以仅返回一个结果。在所有文档中,有一个名为moderatorAssigned
的地图,其ID属性为id,此id是Firebase中用户的uid
。
我有公司,每个公司都有办公室,并且办公室分配了主持人,我想将分配用户的办公室返回到我的组件。
export interface Company {
name: string;
emailAddress: string;
typeOfService: string;
offices: Office[];
}
export interface CompanyId extends Company {
id: string;
}
export interface Office {
id: string;
name: string;
address: string;
moderatorAssigned: {
firstName: string;
id: string;
lastName: string;
};
}
组件
export class SeeTurnsComponent implements OnInit {
officeAssigned: Observable<Office>;
constructor(private companyService: CompanyService,
private authService: AuthService) {
}
ngOnInit() {
const userId = this.authService.getUserUid();
this.officeAssigned = this.companyService.getOfficeAssigned(userId);
}
}
模板
<div *ngIf="officeAssigned | async as office">
{{office.id}}
</div>
服务
private companiesCollection: AngularFirestoreCollection<Company>;
companies: Observable<CompanyId[]>;
constructor(private afs: AngularFirestore) {
this.companiesCollection = afs.collection<Company>(
config.collection_companies,
ref => ref.orderBy('createdAt', 'desc')
);
this.companies = this.companiesCollection.snapshotChanges().pipe(
map(actions => actions.map(a => {
const data = a.payload.doc.data() as Company;
const id = a.payload.doc.id;
return {id, ...data};
}))
);
}
getOfficeAssigned(userId: string): Observable<Office> {
this.companies.pipe(
map(companies => companies.filter(company => {
company.offices.filter(office => {
console.log('comparing...');
if (office.moderatorAssigned && office.moderatorAssigned.id === userId) {
console.log('office found...');
return office;
} else {
console.log('no office assigned...');
return of(null);
}
});
}))
);
return of(null);
}
没有数据,也许我做错了。
我的目标是在服务中的companies: Observable<CompanyId[]>
内搜索并返回已分配用户的办公室,以在模板中显示数据。
答案 0 :(得分:2)
您的代码中有很多问题:
getOfficeAssigned(userId: string): Observable<Office> {
this.companies.pipe(
map(companies => companies.filter(company => {
company.offices.filter(office => {
console.log('comparing...');
if (office.moderatorAssigned && office.moderatorAssigned.id === userId) {
console.log('office found...');
return office;
} else {
console.log('no office assigned...');
return of(null);
}
});
}))
);
return of(null);
}
首先,您的方法始终返回of(null)
。这是没有意义的。您想返回通过转换this.companies
获得的Observable。
因此,代码应类似于:
getOfficeAssigned(userId: string): Observable<Office> {
return this.companies.pipe(
map(companies => this.findOfficeWithAssignedUserId(companies, userId))
);
}
然后实现findCompanyWithAssignedUserId
方法并进行测试。请注意,它不需要使用任何与Observable相关的类型或方法。它只需要find
该数组的元素。看起来应该像
findOfficeWithAssignedUserId(companies: Array<Company>, userId: string): Office {
const company = companies.find(c =>
c.offices.some(office =>
office.moderatorAssigned.id === userId
)
);
return company && company.offices.find(office =>
office.moderatorAssigned.id === userId
);
}
使用flatMap,代码会更好,但是flatMap仍处于试验阶段。还有其他方法可以使该循环更有效,但这应该足够快并能为您提供思路。