Reducer .forEach returns error "No exact matches..."

Hi, I'm hoping you will be able to help with an issue that I am having.

I'm using the docs here... ComposableArchitecture - Reducer(state:action:environment:breakpointonnil:::)

To create a forEach store. But when the code is complete I just get an error "No exact matches in call to instance method forEach"

I'm trying to create a forEach reducer on a computed var which is an IdentifiableArray that has been filtered and sorted and merging a few bits of data.

I have a Launch struct and a Rocket struct both of these stored in State separately. I'm just trying to compile them together so I have a struct like... (Just setting rocket to nil for now to try and get this working).

struct Launch: Identifiable {
    var id: String
    //...
}
struct LaunchState: Identifiable {
    var id: String
    var launch: Launch
    var rocket: Rocket?
}

And in my AppState struct I have a computed var like...

struct AppState: Equatable {
    var launches: IdentifiedArrayOf<Launch> = []
    var sortedFilteredLaunches: IdentifiedArrayOf<LaunchState> {
        let sortedArray = self.launches
            .map { launch -> LaunchState in
                return LaunchState(id: launch.id, launch: launch, rocket: nil)
            }
        
        return IdentifiedArray(sortedArray)
    }

In the Launch.swift file I have two reducers (again, only while trying to work out why this isn't working...

let launchStateReducer = Reducer<LaunchState, LaunchAction, LaunchEnvironment> {
    state, action, _ in
    switch action {
    case .launchTapped:
        return .none
    }
}

let launchReducer = Reducer<Launch, LaunchAction, LaunchEnvironment> {
    state, action, _ in
    switch action {
    case .launchTapped:
        return .none
    }
}

In the appReducer if I do this it works...

    launchReducer.forEach(
        state: \AppState.launches,
        action: /AppAction.launchAction(id:action:),
        environment: { _ in LaunchEnvironment() }
    ),

But with this it doesn't...

    launchStateReducer.forEach(
        state: \AppState.sortedFilteredLaunches,
        action: /AppAction.launchAction(id:action:),
        environment: { _ in LaunchEnvironment() }
    ),

It shows the error No exact matches in call to instance method 'forEach' but I can't work out why.

I was wondering if someone could help out here. Am I doing something drastically wrong with trying to create this reducer?

Thanks

I may be wrong, but the biggest difference I can see is that AppState.sortedFilteredLaunches is a computed property. Does it work if you set it in initialiser? I see that the issue with that, is then you won't get a LaunchState automatically from your launches, but this could also be worked around with setter?

1 Like

Oh man, I'm an idiot. Haha! Your reply made me go back to here... swift-composable-architecture/Todos.swift at main · pointfreeco/swift-composable-architecture · GitHub

... and read it in more depth.

It looks like what is happening is they are creating the filtered array in a computed var and using it to scope the store. But the reducer is working on the todos rather than the filtered array. Thinking about it, this makes absolute sense as you would never be able to run an action and update the state in the computed var. But that doesn't matter as long as you update the actual underlying var.

Thanks for your reply. It made me think about the problem in a different way (and finally understand it).

Will try and play around and update with what I find.

1 Like
Terms of Service

Privacy Policy

Cookie Policy