skip to Main Content

(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.

Workaround: link 1 link 2

2

Answers


  1. 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 => {...
    
    Login or Signup to reply.
  2. 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() )
        );
      });
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search