I am currently working on developing code that paginates a result set using the expand operator until a specific number of resources have been fetched. Below is the code snippet I have written so far (excluding the actual async call logic):
import { Observable } from 'rxjs';
const items = [
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
];
const call = () => {
console.log('#call');
const batch = items.shift();
if (batch) {
return Observable.of(batch).delay(100);
}
return Observable.empty();
}
const o$ = call().expand((values) => {
console.log('expansion');
return call();
}).flatMap((val: any) => val);
const log = (prefix: string) => (...args: any[]) => console.log(prefix, ...args);
o$.take(9).subscribe(log('next'), log('error'), log('complete'));
The output is not as desired:
#call
takeWhile.ts:26 next 1
takeWhile.ts:26 next 2
takeWhile.ts:26 next 3
takeWhile.ts:26 next 4
takeWhile.ts:26 next 5
takeWhile.ts:26 next 6
takeWhile.ts:26 next 7
takeWhile.ts:26 next 8
takeWhile.ts:26 next 9
takeWhile.ts:26 complete
takeWhile.ts:22 expansion
takeWhile.ts:10 #call
Although I receive the 9 items as requested with take
, the stream completes, but an additional expansion occurs and the mock async API is called again.
Is there a way to modify my code to prevent this extra recursive iteration and make it less eager?