Issue
The following code should execute multiple long-running HTTP requests sequentially:
- First HTTP request is started
- First HTTP request is finished
- Second HTTP request is started
- Second HTTP request is finished
- Third HTTP request is started
- ...
Some of the requests can take up to 30 seconds, so the code needs to make sure that second request waits for the first request to finish. In addition, there needs to be one request for every id provided by this.service.getAll()
.
However, I was not able to achieve the desired behavior with following code. Instead, after the completion of the first HTTP request (30 seconds) no further requests were sent. My assumption is that concatMap
somehow does not buffer the other accounts while waiting for the current request to complete.
Component:
this.service.getAll().pipe(
concatAll(), // flatten the observable
concatMap(acc => this.service.update(acc.id, {synchronize: true}).pipe(delay(1000)))
).subscribe(() => {
this.someFlag = false;
});
Service:
getAll(): Observable<Account[]> {
return this.http.get<Account[]>('someUrl');
}
// The request can take up to 30 seconds
update(id: number, account: Account): Observable<Account> {
return this.http.put<Account>('someUrl', account);
}
How can I achieve the desired behavior?
Solution
Make sure that your observables completes after emitting once by using take(1)
or first()
.
this.service.getAll().pipe(
concatMap(acc => this.service.update(acc.id, {synchronize: true}).pipe(take(1), delay(1000)))
).subscribe(() => {
this.someFlag = false;
});
You also may want to do some error handling, but that's another case.
Answered By - s.alem
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.