In my application, I came across a strange behavior related to combineLatest
operator. I reproduced this issue with the online demo:
Note: Please ignore this business logic in this demo, it's not that reasonable, I just want to reproduce this issue in technical level.
https://stackblitz.com/edit/angular-qcdslo?file=src/app/app.component.ts
private testRequest() {
this.pokemon$ = combineLatest(this.limit$, this.offset$)
.pipe(
map(data => ({limit: data[0], offset: data[1]})),
switchMap(data => this.pokemonService.getPokemon(data.limit, data.offset)),
map((response: {results: Pokemon[]}) => response.results),
);
}
this method use combineLatest to combine two observables: limit$ and offset$. And sent request to the API where the value of limit and offset are just parameters for the API.
And I increase the counter value by 1 per 5 seconds in the following methods:
let counter = 1
setInterval(() => {
this.offsetControl.setValue(counter)
counter++;
}, 5000)
Finally, for some reason I need to call the testRequest method intervally per 6s as well in the following way:
setInterval(() => {
this.testRequest();
}, 6000)
Then the network request behavior is as below:
limit=5&offset=0
limit=5&offset=1
limit=5&offset=0
limit=5&offset=2
limit=5&offset=0
limit=5&offset=3
...
limit=5&offset=0
limit=5&offset=n
I don't understand why the limit=5&offset=0
happened repeatedly. Thank you.
Everytime testRequest executes you are creating a new observable, this is not what you want to do, everytime you recreate the observable you are getting the startsWith value that was zero when you called startsWith.
Get rid of the combine latest and just pull the values from the form controls.
https://stackblitz.com/edit/angular-droqf6?file=src/app/app.component.ts