Search code examples
angularionic-frameworkrxjsangularfire

identify last object within mergeMap


i want to merge my ranking entity with my member entity in ionic4/angular7.

what i actually do is:

this.rankingObs = this.rankingService.getAll().pipe(
  mergeMap(ranking => { 
    ranking.forEach(rank => {
      this.membersService.get(rank.key).subscribe(member => {
        rank.firstName = member.firstName;
        rank.lastName = member.lastName;
        rank.keyName = member.key;
      })
    });
  return ranking;
  }),
).subscribe((merged) => {
  let ranking = merged as RankingModelAll;
  this.rankingmodel.push(ranking);

   //***
   //CAN'T BE CORRECT HERE :( i only want to sort at last and also set the preloadingDone at Last
  this.rankingmodel = this.rankingmodel.sort((n1,n2) => {
    if(n1.points < n2.points) {
      return 1;
    }
    if(n1.points > n2.points) {
      return -1;
    }
    return 0;
  });
  this.preloadingDone = true;
  // ****
});

merging my members names into the ranking model, but how can i identify the last run of my merged entity to set my preloadingDone flag to true and do the sorting of top rank?


Solution

  • I have few comments about your code.

    1. Nested subscribe is not very good practice. You should flatten it.
    2. Use subscribe(next, error, complete) complete handler to set your flag preloadingDone to done
    3. In your case I would use insert into sorted array, instead of sorting whole array at the end.

    Take a look at snippet bellow:

        const orderedInsert = compareFn => (array, item) => {/** need to code this :( */};
    
    const insetRank = orderedInsert((n1,n2) => {
            // your compare fn
            if(n1.points < n2.points) {
              return 1;
            }
            if(n1.points > n2.points) {
              return -1;
            }
            return 0;
          }
    );
    
    this.rankingObs = this.rankingService.getAll().pipe(
      mergeMap(ranking => from(ranking))
      mergeMap(rank =>this.membersService.get(rank.key).pipe(map(member => ({
          ...rank,
          ...member 
      }))
    ).subscribe((rankMerged:RankingModelAll) => 
      insetRank(this.rankingmodel, rankMerged), 
      e => console.log(e), 
      () => {
        this.preloadingDone = true;
        console.log('Done')
     });