Not sure if this answers your question (couldn't post a comment to ask for specifics). But assuming the other back end calls also depend only on an element from this.etiquetasEjeX
you could use the zip
operator. However regarding the usage of concatMap
the four request would be performed simultaneously per item. If you were restricted to one api call at a time this solution would need some adjustments.
import { of, zip } from 'rxjs';
import { concatMap, toArray } from 'rxjs/operators';
//...
of(...this.etiquetasEjeX)
.pipe(
concatMap(item=>
zip(
this.dataService.getGastadoRealizadoEnMesYAño(...),
this.dataService.getB...,
this.dataService.getC...,
this.dataService.getD...,
),
toArray(),
)
.subscribe((arr: [ItemA, ItemB, ItemC, ItemD][])=> {
//...
});
Edit:
okay in your comment you mentioned that a subsequent request depends on the result of a prior request. Nesting concatMap
operations like your initially requested would be a little messy as you can see in the following example:
of(...this.etiquetasEjeX)
.pipe(
concatMap(item=>
this.dataService.getGastadoRealizadoEnMesYAño(...).pipe(
concatMap(itemA =>
this.dataService.getB(itemA).pipe(
concatMap(itemB =>
this.dataService.getC(itemB).pipe(
concatMap(itemC =>
this.dataService.getD(itemC).pipe(
map(itemD =>
// every combination of items would be available here
this.getGraph(item, itemA, itemB, itemC, itemD)
)
)
)
)
)
)
)
)
),
toArray(),
)
.subscribe(graphs => {
// graphs array contains elements that were returned by this.getGraph
});
But the same operations could also be called sequentially without losing the intermediate results that you will need for feeding your graph:
of(...this.etiquetasEjeX)
.pipe(
concatMap(item=> combineLatest(
of(item),
this.dataService.getA(item, ...),
)),
concatMap(([item, itemA]) =>
this.dataService.getB(itemA, ...)
combineLatest(
of([item, itemA]), // it's important that the elements are enclosed inside an array here otherwise the of operator fires twice and doesn't have the proper effect
,
)),
concatMap(([prevItems, itemB]) => combineLatest(
of([...prevItems, itemB]),
this.dataService.getC(itemB, ...),
)),
concatMap(([prevItems, itemC]) => combineLatest(
of([...prevItems, itemC]),
this.dataService.getD(itemC, ...),
)),
map(([item, itemA, itemB, itemC, itemD]) =>
this.getGraph(item, itemA, itemB, itemC, itemD)
),
toArray(),
)
.subscribe(graphs => {
// update the state of your object eg.
this.myGraphs = graphs;
});
And I noticed that you are using toArray
. That means your observable won't provide you with any intermediate results until all your api calls have been finished. Depending on the size of the resulting arrays provided by your api the given solution might be quite time and memory consuming.