I'm using an API that returns only a limited number of results, say 100.
I'd like to repeat a query until the return result set is < 100
which would mean I've got the last result.
So it would go like this:
stop$: Subject = new Subject();
query$.pipe(takeUntil(this.stop$)).subscribe( result => {
if(result < limit)
this.stop$.next();
this.stop$.complete();
}
else {
process result, i.e append somewhere...
}
});
Note his is the RxJs 6 syntax. For readability you can extract the subscribe logic in a method.
Maybe working with takeWhile is easier in this case:
doQuery: boolean = true;
query$.pipe(takeWhile(()=> this.doQuery).subscribe( result => {
if(result < limit)
this.doQuery = false;
}
else {
process result, i.e append somewhere...
}
});
We can also use the repeat operator:
this.queryData().pipe(
repeat(),
filter(data => this.checkLimit()),
take(1)
).subscribe(result => console.log(result));
Note: the take(1)
is needed to stop the repeat
loop.
If we need a delay between retries, we can do:
repeat({delay: 1000})
You can use the expand operator for a simple "conditional repeat" behavior.
Just for the example, instead of a result set I changed the query to return a number. The following keep querying until the retrieved number is less than 100
const { defer, empty } = rxjs;
const { expand, toArray} = rxjs.operators;
const query$ = defer(async () => Math.floor(Math.random()*1000));
query$
.pipe(
expand(result => result < 100 ? empty() : query$),
toArray()
)
.subscribe(console.log);
<script src="https://unpkg.com/rxjs/bundles/rxjs.umd.min.js"></script>
You can also use RXJS Interval with TakeWhile operator. Here is the sample code
In Component:
return Observable
.interval(250)
.flatMap(() => this.getQueryData())
.takeWhile(data => this.checklimit(data))
.subscribe(result => console.log(result);
getQueryData(){
// HTTTP API call
}
checklimit(){
// return true/false
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With