I am calling a function to get a result which is an AnyPublisher<[Object], Error>
. Now I need to loop through each object and call at least 3 another api calls with the id in a single object.
AnyPublisher<[Object], Error>
|
Loop though the object array
|
with a property in the object, make 3 api calls(async or sync)
|
with the object and the objects i get from each api call, create another object and publish it
How can I do this?
Edit: This is some code that I added to check whether this will work. This is based on the code I found on one of your other posts Combine framework: how to process each element of array asynchronously before proceeding But instead of collecting all the publishers and then coming to map, its going to map after completing the inner flatMap.
What am I doing wrong?
struct FoodDetailInput {
let appear: AnyPublisher<Void, Never>
}
let appearRecord = PassthroughSubject<Void, Never>()// this is called when the detail page is taken
let input = FoodDetailInput(appear: appearRecord.eraseToAnyPublisher())
let foodDetails = input.appear
.flatMap({[unowned self] _ in self.dataProvider.ingredients(for: food.id) })
.flatMap({ ingredients -> AnyPublisher<Ingredient, Error> in
Publishers.Sequence(sequence: ingredients).setFailureType(to: Error.self).eraseToAnyPublisher()
})
.flatMap({[unowned self] singleIngredient in
self.dataProvider.variants(for: food.id, ingredientName: singleIngredient.id)
.flatMap { variants -> AnyPublisher<DetailPageObject, Error> in
var singleDetailObject = DetailPageObject(ingredient: singleIngredient)
singleDetailObject.variants = variants
return Just(singleDetailObject).setFailureType(to: Error.self).eraseToAnyPublisher()
}
.collect()
.map { detailPageObjects -> PageDetailsState in
PageDetailsState.success(detailPageObjects)
}
})
.replaceError(with:PageDetailsState.success([]))
.eraseToAnyPublisher()
You are describing .flatMap
. Three API calls? You can just chain three .flatMap
calls — though if you prefer to do them simultaneously you can configure them in an array and use .flatMap
on that. If you use the former approach, uou will need to keep passing both the object (or the accumulated objects) and the id
down the chain as you go so that everything you need pops out the end.