英文:
Combine Observable subscription results in Angular
问题
(1) 我在Firebase Firestore中发出一个请求,从一个集合中获取了多个 'nomBu' 字符串。 已完成
(2) 然后,使用这些恢复的 'nomBu' 字符串,我发出第二个请求,从另一个包含 'nomBu' 的集合中获取元数据。 已完成
(3) 我想在HTML仪表板中显示数据。 已完成 但我只能在我的仪表板中获取一个可观察结果(最后一个执行的)。
我的代码(1、2和3)
demandesSaaSEvaluator: Demande[];
fire.collection('businessUnit')
.where('evaluators', 'array-contains', this.auth.currentUserEmail).get() //(1)
.then(snapshot => {
snapshot.forEach(doc => {
//对于每个匹配的 'nomBu' 获取其元数据
this.service.getEvaluatorSaaSRequests(doc.data().nomBu).subscribe(actionArray => { //(2)
this.demandesSaaSEvaluator = actionArray.map(item => {
return { //在HTML中显示 (3)
id: item.payload.doc.id,
...(item.payload.doc.data() as object)
} as Demande;
});
});
});
});
我的代码(2)
getEvaluatorSaaSRequests(nomBu) { //应该被多次执行
return this.firestore
.collection('solutions', ref =>
ref.where('businessUnitOfSolution', '==', nomBu).where('type', '==', 'SaaS')
)
.snapshotChanges();
}
我的代码(3)
<tbody>
<tr *ngFor="let demande of demandesSaaSEvaluator; let i = index">
<td>{{ demande.id }}</td>
<td>{{ demande.solutionName }}</td>
<td>{{ demande.nomBu }}</td>
<td>{{ demande.user }}</td>
</tr>
</tbody>
使用这段代码,我只能显示/获取一个可观察结果(最后一个执行的) => 我想要合并所有可观察订阅结果,以显示包含所有执行请求结果的仪表板。
英文:
(1) I have a request in Firebase firestore where I get several 'nomBu' strings from a collection. OK
(2) Then, with these recovered 'nomBu' strings, I make a second request to get metedata from another collection where the 'nomBu' is present. OK
(3) I would like to display data in a dashboard in HTML. OK But I can only get 1 observable result in my dashboard (the last one executed)
My code (1 and 2 and 3)
demandesSaaSEvaluator: Demande[];
fire.collection('businessUnit')
.where('evaluators', 'array-contains', this.auth.currentUserEmail).get() //(1)
.then(snapshot => {
snapshot.forEach(doc => {
//for each matching 'nomBu' get his metadata
this.service.getEvaluatorSaaSRequests(doc.data().nomBu).subscribe(actionArray => { //(2)
this.demandesSaaSEvaluator = actionArray.map(item => {
return { //display in HTML (3)
id: item.payload.doc.id,
...(item.payload.doc.data() as object)
} as Demande;
});
});
});
});
My code (2)
getEvaluatorSaaSRequests(nomBu) { //should be executed several time
return this.firestore
.collection('solutions', ref =>
ref.where('businessUnitOfSolution', '==', nomBu).where('type', '==', 'SaaS')
)
.snapshotChanges();
}
My code (3)
<tbody>
<tr *ngFor="let demande of demandesSaaSEvaluator; let i = index">
<td>{{ demande.id }}</td>
<td>{{ demande.solutionName }}</td>
<td>{{ demande.nomBu }}</td>
<td>{{ demande.user }}</td>
</tr>
</tbody>
With that code I can only display/get one observable result (the last one executed) => I would like to combine all observable subscription results to display the dashboard with all executed request results.
答案1
得分: 1
demandesSaaSEvaluator
在observable发出内容时每次都会被重新分配。如果想保留先前的值,应将demandesSaaSEvaluator
设为数组,并在每次调用回调时推送新值:
this.service.getEvaluatorSaaSRequests(doc.data().nomBu).subscribe(actionArray => {
this.demandesSaaSEvaluator.push(actionArray.map(item => {
return {
id: item.payload.doc.id,
...(item.payload.doc.data() as object)
} as Demande;
}));
});
如果想在模板中以单一列表显示所有元素,可以使用展开运算符:
this.demandesSaaSEvaluator.push(...actionArray.map(item => {...}));
英文:
demandesSaaSEvaluator
is reassign every time the observable emit something. If you want to keep the previous values, you should make demandesSaaSEvaluator
an array and push a new value every time the callback is called :
this.service.getEvaluatorSaaSRequests(doc.data().nomBu).subscribe(actionArray => {
this.demandesSaaSEvaluator.push(actionArray.map(item => {
return {
id: item.payload.doc.id,
...(item.payload.doc.data() as object)
} as Demande;
}));
});
If you want a flat array to displat all the elements in a single list in your template, you can use the spread operator like this :
this.demandesSaaSEvaluator.push(...actionArray.map(item => {...
答案2
得分: 1
你可以压缩你的可观察对象并返回所需的结果:
fire
.collection("businessUnit")
.where("evaluators", "array-contains", this.auth.currentUserEmail)
.get() //(1)
.then((snapshot) => {
zip(
snapshot.docs.map((doc) => {
return this.service.getEvaluatorSaaSRequests(doc.data().nomBu).pipe(
map((actionArray) =>
actionArray.map((item) => ({
id: item.payload.doc.id,
...(item.payload.doc.data() as object),
}))
)
);
}).subscribe(result => this.demandesSaaSEvaluator = result.flat() )
);
});
英文:
You can zip your observable and return the return the desire result:
fire
.collection("businessUnit")
.where("evaluators", "array-contains", this.auth.currentUserEmail)
.get() //(1)
.then((snapshot) => {
zip(
snapshot.docs.map((doc) => {
return this.service.getEvaluatorSaaSRequests(doc.data().nomBu).pipe(
map((actionArray) =>
actionArray.map((item) => ({
id: item.payload.doc.id,
...(item.payload.doc.data() as object),
}))
)
);
}).subsribe(result => this.demandesSaaSEvaluator = result.flat() )
);
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论