Search code examples
typescriptrxjsobservablerxjs-pipeable-operators

RxJS missing values when using combineAll with 2 observables


I'm trying to generate overs for a cricket match simulation with values as follows:

Overs -> 0 - 19 (total 20 overs)
Balls -> 1 - 6 (total 120, each over has 6 balls)

Hence the sequence that has to be generated would be something like 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 1.1, 1.2, 1.3, ....., 19.4, 19.5, 19.6

I can easily achieve this by iterating, using 2 nested loops, but since I am using angular with RxJS, I wanted to do this the reactive way. I came up with the following code which should work AFAIK:

import { range } from 'rxjs';
import { map, combineAll } from 'rxjs/operators';

let overs = range(0, 20);

let balls = range(1, 6);

let ob = overs.pipe(
  map((over) => balls.pipe(
    map((ball) => `${over}.${ball}`)
  ))
).pipe(combineAll())

ob.subscribe((val) => console.log(val));

But the problem with this is, it is missing a lot of values. I get the following output:

[ '0.6',
  '1.6',
  '2.6',
  '3.6',
  '4.6',
  '5.6',
  '6.6',
  '7.6',
  '8.6',
  '9.6',
  '10.6',
  '11.6',
  '12.6',
  '13.6',
  '14.6',
  '15.6',
  '16.6',
  '17.6',
  '18.6',
  '19.1' ]
[ '0.6',
  '1.6',
  '2.6',
  '3.6',
  '4.6',
  '5.6',
  '6.6',
  '7.6',
  '8.6',
  '9.6',
  '10.6',
  '11.6',
  '12.6',
  '13.6',
  '14.6',
  '15.6',
  '16.6',
  '17.6',
  '18.6',
  '19.2' ]
[ '0.6',
  '1.6',
  '2.6',
  '3.6',
  '4.6',
  '5.6',
  '6.6',
  '7.6',
  '8.6',
  '9.6',
  '10.6',
  '11.6',
  '12.6',
  '13.6',
  '14.6',
  '15.6',
  '16.6',
  '17.6',
  '18.6',
  '19.3' ]
[ '0.6',
  '1.6',
  '2.6',
  '3.6',
  '4.6',
  '5.6',
  '6.6',
  '7.6',
  '8.6',
  '9.6',
  '10.6',
  '11.6',
  '12.6',
  '13.6',
  '14.6',
  '15.6',
  '16.6',
  '17.6',
  '18.6',
  '19.4' ]
[ '0.6',
  '1.6',
  '2.6',
  '3.6',
  '4.6',
  '5.6',
  '6.6',
  '7.6',
  '8.6',
  '9.6',
  '10.6',
  '11.6',
  '12.6',
  '13.6',
  '14.6',
  '15.6',
  '16.6',
  '17.6',
  '18.6',
  '19.5' ]
[ '0.6',
  '1.6',
  '2.6',
  '3.6',
  '4.6',
  '5.6',
  '6.6',
  '7.6',
  '8.6',
  '9.6',
  '10.6',
  '11.6',
  '12.6',
  '13.6',
  '14.6',
  '15.6',
  '16.6',
  '17.6',
  '18.6',
  '19.6' ]

As one can observe, all overs are generated (0-19) but we are getting only the .6 values with each. Only the last over, i.e. 19th is having unique values 19.1, 19.2...

What am I missing in this code?

Also, if it helps here's the repl for the above code in case you want to try and experiment with it in browser: https://repl.it/@ishankhare07/cricket-overs


Solution

  • You don't even need to use combineAll and use mergeMap instead which makes it more understandable.

    import { range } from 'rxjs';
    import { map, mergeMap } from 'rxjs/operators';
    
    let overs = range(0, 20);
    let balls = range(1, 6);
    
    let ob = overs.pipe(
      mergeMap((over) => balls.pipe(
        map((ball) => `${over}.${ball}`),
      )),
    ); 
    
    ob.subscribe((val) => console.log(val));
    

    Live demo: https://stackblitz.com/edit/rxjs-aud3ot