Combine Observable subscription results in Angular.

huangapple go评论51阅读模式
英文:

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 链接 2

英文:

(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(&#39;businessUnit&#39;)
.where(&#39;evaluators&#39;, &#39;array-contains&#39;, this.auth.currentUserEmail).get() //(1)
          .then(snapshot =&gt; {
            snapshot.forEach(doc =&gt; {
//for each matching &#39;nomBu&#39; get his metadata
this.service.getEvaluatorSaaSRequests(doc.data().nomBu).subscribe(actionArray =&gt; { //(2)
              this.demandesSaaSEvaluator = actionArray.map(item =&gt; {
            
                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(&#39;solutions&#39;, ref =&gt; 
        ref.where(&#39;businessUnitOfSolution&#39;, &#39;==&#39;, nomBu).where(&#39;type&#39;, &#39;==&#39;, &#39;SaaS&#39;)
      )
      .snapshotChanges();
  }

My code (3)

&lt;tbody&gt;
    &lt;tr *ngFor=&quot;let demande of demandesSaaSEvaluator; let i = index&quot;&gt;
      &lt;td&gt;{{ demande.id }}&lt;/td&gt;
      &lt;td&gt;{{ demande.solutionName }}&lt;/td&gt;
      &lt;td&gt;{{ demande.nomBu }}&lt;/td&gt;
      &lt;td&gt;{{ demande.user }}&lt;/td&gt;
    &lt;/tr&gt;
&lt;/tbody&gt;

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.

Workaround: link 1 link 2

答案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 =&gt; {               
  this.demandesSaaSEvaluator.push(actionArray.map(item =&gt; {
    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 =&gt; {...

答案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(&quot;businessUnit&quot;)
  .where(&quot;evaluators&quot;, &quot;array-contains&quot;, this.auth.currentUserEmail)
  .get() //(1)
  .then((snapshot) =&gt; {
    zip(
      snapshot.docs.map((doc) =&gt; {
        return this.service.getEvaluatorSaaSRequests(doc.data().nomBu).pipe(
          map((actionArray) =&gt;
            actionArray.map((item) =&gt; ({
              id: item.payload.doc.id,
              ...(item.payload.doc.data() as object),
            }))
          )
        );
      }).subsribe(result =&gt; this.demandesSaaSEvaluator = result.flat() )
    );
  });

huangapple
  • 本文由 发表于 2023年5月10日 18:38:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76217405.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定