Reputation: 2475
Here's the problem statement:
/api/postsomedata
) and (/api/postsomeotherdata
)I came up with following rxjs implementation using nested concatMap
:
import { range } from 'rxjs/observable/range';
import { concatMap } from 'rxjs/operators';
import { tap } from 'rxjs/operators/tap';
@Component({
selector: 'app-flow',
templateUrl: './flow.component.html',
styleUrls: ['./flow.component.scss']
})
export class FlowComponent implements OnInit {
constructor(public dataCallService: DataCallService) { }
ngOnInit() {
range(1, 100).pipe(
tap((d) => console.log(d)),
concatMap(() => this.dataCallService.firstAPI(data1).pipe(
concatMap(() => this.dataCallService.secondAPI(data2))
))
).subscribe(res => {
console.log(res)
});
}
}
Although this works fine; tap
operator I used emits 1 to 100 immediatly. I am not sure whether its correct approach.
Is there any better approach to achieve the same ?
Upvotes: 2
Views: 512
Reputation: 222760
In order for the requests to be chained, it should be something like:
Observable.range(1, 100).map(i =>
this.dataCallService.firstAPI(data1)
.concatMap(() => this.dataCallService.secondAPI(data2))
})
.concatAll()
.subscribe(res => {});
Request observables can be conveniently handled with promises in Angular, because both Http
and HttpClient
result in complete observable with single value.
Unless request observable is supposed to be aborted in the middle of a request or piped with other incomplete/multi-value observables, it may be beneficial to switch to promises.
This results in very straightforward async
function where Promise.all
is used for requests that can be performed in parallel:
async ngOnInit() {
try {
for (let i = 0; i < 100; i++) {
const [result1, result2] = await Promise.all([
this.dataCallService.firstAPI(data1).toPromise(),
this.dataCallService.secondAPI(data2).toPromise()
]);
}
} catch (err) { ... }
}
Or in series:
async ngOnInit() {
try {
for (let i = 0; i < 100; i++) {
const result1 = await this.dataCallService.firstAPI(data1).toPromise();
const result2 = await this.dataCallService.secondAPI(data2).toPromise();
}
} catch (err) { ... }
}
Upvotes: 2