Home > Software engineering >  RxJS combineLatest add timer to only one observable
RxJS combineLatest add timer to only one observable

Time:06-26

I have two entities, Games and Jackpots:
Game interface

{
    id: string,
    name: string
}

Jackpot interface

{
    game: string,
    amount: number
}

First I have two observables, one to get games and one to get jackpots.
And after getting the data i want to merge the data of jackpots into games based on id. And since the jackpots observale should get the data each seconds i used the operator timer to do so. So here's my implementation:

private getGames = (category: string): Observable<IGame[]> => {
        return timer(0, 3000).pipe(
            mergeMap(() => combineLatest([this.gameService.getGames(), this.gameService.getJackpots()])),
            map(([games, jackpots]) => {
                return games?.filter(game => game?.categories?.includes(category))?.map(game => {
                    return { ...game, jackpot: jackpots?.find(jackpot => jackpot?.game === game?.id) };
                })
            })
        );
    };

This implementation works fine and the data is fetched every 3 seconds. Now as you can see both Games and Jackpots observable get fetched every 3 seconds, My question is: is there a way to only run the Jackpots observable every 3 seconds, and exclude the Games observable from that timer.

CodePudding user response:

Context

combineLatest has two important properties:

  • it emits every time any of the Observables emits a value.
  • it requires all source Observables to emit at least one value.

Solution

You can set the timer only for the games Observable and combine it with the jackpots one.

private getGames = (category: string): Observable<IGame[]> => {
  return combineLatest([
    timer(0, 3000).pipe(mergeMap(() => this.gameService.getGames())),
    this.gameService.getJackpots(),
  ]).pipe(
    map(([games, jackpots]) => {
      return games
        ?.filter((game) => game?.categories?.includes(category))
        ?.map((game) => {
          return { ...game, jackpot: jackpots?.find((jackpot) => jackpot?.game === game?.id) };
        });
    })
  );
};
  • Related