Hi I came across the following on combine publishers:
And specifically the part:
private extension TaskGroupsLoader {
func loadGroups(
for entries: [Entry]
) -> AnyPublisher<[Task.Group], Error> {
// First, we convert our Entry array into a publisher:
entries.publisher
// Then, we use the flatMap operator to convert
// each Entry element into a nested publisher using
// the loadGroup method that we implemented earlier:
.flatMap(loadGroup)
// Finally, we collect the results from all of our
// nested publishers into one final array of task groups:
.collect()
.eraseToAnyPublisher()
}
}
But I'm having a hard time matching this with the Effect
type.
I'm currently stuck at using .collect()
which doesn't work on a collection/array of effects. I've seen zip on Combine Publishers but they don't seem to be made for a collection of effects of variable size. Any tips on how to do this would be greatly appreciated! :)
Here's a simplified version of my code:
enum Action {
case onAppear
case responses([APIResponse]) // This can also be of type Result<[APIResponse], APIError> or [Result<APIResponse, APIError>] depending on what happens in the reducer
}
struct Environment {
let apiRequest: (APIQuery) -> Effect<APIResponse, APIError>
}
let reducer = Reducer<State, Action, Environment> { state, action, env in
switch action {
case .onAppear:
let queries: [APIQuery] = returnRandomAmountOfQueries()
let effects = queries.map(env.apiRequest)
return effects.collect().map(Action.responses).eraseToEffect()
case let .responses(responses):
print(responses)
return .none
}
}
To summarize I would like to be able to send a variable amount of effects and group their results, send an action back to the reducer with their collected results once all effects have finished.