Home > database >  Angular/RxJS: forkjoin with more than 6 parameters
Angular/RxJS: forkjoin with more than 6 parameters

Time:12-04

I use forkjoin to initialize data before loading my page. Unfortunately I have reached the limit of 6 parameters for forkjoin:

export class Sample implements OnInit {

  list1?: Pair[];
  list2?: Pair[];
  list3?: Pair[];
  list4?: Pair[];
  list5?: PairExt[];
  list6?: PairExt[];
  list7?: PairExt[];

  constructor(private http: HttpService,
              private httpWithCaching: HttpWithCachingService) {
  }

  ngOnInit(): void {
    this.initLists().subscribe(([list1, list2, list3, list4, list5, list6, list7]) => {
      this.list1 = list1;
      this.list2 = list2;
      this.list3 = list3;
      this.list4 = list4;
      this.list5 = list5;
      this.list6 = list6;
      this.list7 = list7;

      this.initModule();
    });
  }

  initLists(): Observable<[Pair[], Pair[], Pair[], Pair[], PairExt[], PairExt[], PairExt[]]> {
    return forkJoin([
      this.httpWithCaching.getList1(),
      this.httpWithCaching.getList2(),
      this.httpWithCaching.getList3(),
      this.httpWithCaching.getList4(),
      this.httpWithCaching.getList5(),
      this.httpWithCaching.getList6(),
      this.httpWithCaching.getList7()
    ]);
  }

  initModule(): void {
     //some requests and initialization after the lists were fetched...
  }

The code above will therefore no longer work as forkjoin is lmited to 6 parameters.

What would be the most simple solution for my case? All I want to do really is to fetch the lists before calling my initModule...

Thanks in advance!

CodePudding user response:

NB: Not Tested

Try below to group the forkJoins

   return forkJoin([
    forkJoin([
      this.httpWithCaching.getList1(),
      this.httpWithCaching.getList2(),
      this.httpWithCaching.getList3(),
      this.httpWithCaching.getList4(),
      this.httpWithCaching.getList5(),
      this.httpWithCaching.getList6(),
    ]),
    forkJoin([
       this.httpWithCaching.getList7(),
       this.httpWithCaching.getList8(),
    ])

 ]).pipe(
     map( x => x.flat())
  );

The mapping is useful to transform the data back to 1 dimensional array

CodePudding user response:

Perhaps fallback to traditional approach, i.e. Promises. Use Promise.all to make the parallel API calls (similar to forkJoin). Given that in forkJoin would return an Observable nested over API calls that would complete, we can easily replace it with Promise.all


initLists(): Promise<[Pair[], Pair[], Pair[], Pair[], PairExt[], PairExt[], PairExt[]]> {
   const promises = [this.httpWithCaching.getList1(),
      this.httpWithCaching.getList2(),
      this.httpWithCaching.getList3(),
      this.httpWithCaching.getList4(),
      this.httpWithCaching.getList5(),
      this.httpWithCaching.getList6(),
      this.httpWithCaching.getList7()];

   return Promise.all(promises);
}

CodePudding user response:

Do it in other way:

  initLists(): Observable<[Pair[], Pair[], Pair[], Pair[], PairExt[], PairExt[], PairExt[]]> {
    return from([
      this.httpWithCaching.getList1(),
      this.httpWithCaching.getList2(),
      this.httpWithCaching.getList3(),
      this.httpWithCaching.getList4(),
      this.httpWithCaching.getList5(),
      this.httpWithCaching.getList6(),
      this.httpWithCaching.getList7()
    ]).pipe(combineLatestAll());
  }

That's it!

  • Related