navigationDestination with computed properties from SwiftData queries

I have a Query in my View that brings in some data that I then filter with a few different computed properties. I then use those properties to present the data in a view. This is the view (simplified for clarity).

struct FMListView: View {
    @Query(sort: \FMList.name) var fmLists: [FMList]
    
    private var systemTodoLists: [FMList] {
        fmLists.filter { $0.ownership == Ownership.system }
    }
    
    private var userTodoLists: [FMList] {
        fmLists.filter { $0.ownership == Ownership.user && $0.parentList == nil}
    }
    
    private var favoriteTodoLists: [FMList] {
        fmLists.filter { $0.isFavorite }
    }
    
    var body: some View {
        NavigationStack {
            List {
                // MARK: -- System TodoLists
                ForEach(systemTodoLists) { list in
                        NavigationLink(value: list) {
                            Text(list.name)
                        }
                }
                
                Section(header: Text("Favorites").padding(.top, -24)) {
                    ForEach(favoriteTodoLists) { list in
                        NavigationLink(value: list) {
                            Text(list.name)
                        }
                    }
                }
                
                // MARK: -- User TodoLists
                Section(header: Text("Lists").padding(.top, -24)) {
                    ForEach(fmLists.filter { $0.ownership == Ownership.user && $0.parentList == nil}) { list in
                        NavigationLink(value: list) {
                            Text(list.name)
                        }
                    }
                }
            }
            .navigationDestination(for: FMList.self) { list in
                Text(list.name)
// MARK: -- ERROR HERE
                Toggle(isOn: list.isFavorite) {
                    Label("Favorite", systemImage: IconConstants.starIcon)
                }
            }
        }
    }
}

The challenge I have here is that I need to represent the queried data in multiple different formats (for the example, I'm just using a Text view). When I navigate to the navigationDestination I want to edit the state on a property within the model but the model in this scope isn't bindable so I can't pass it into the Toggle.

I'm not sure if the issue is my use of computed properties, or if it's my not understanding binding misusing the Toggle. I'd appreciate some guidance on this use-case - allowing me to pass a bindable version of the model down the stack once filtered on the app side.

On a somewhat related note - I am filtering with computed properties because I can't do this filter within the Query predicate. The following gave me a compiler error because the ownership.user wasn't a constant value.

$0.ownership == Ownership.user

This is what the enum looks like:

enum Ownership: String, CaseIterable, Codable {
    case system = "SYSTEM"
    case user = "USER"
}

I forgot to mention what my model looked like. A simplified version of it looks like this:

@Model class FMList {
    var listID: UUID
    var name: String
    var isFavorite: Bool

    // init func omitted for brevity
}

it looks like I had left some test code in my List example I initially provided. The below code is what I'm actually using (no online filtering, I'm using the computed property) For the user todo lists section.

                // MARK: -- User TodoLists
                Section(header: Text("Lists").padding(.top, -24)) {
                    ForEach(userTodoLists) { list in
                        NavigationLink(value: list) {
                            Text(list.name)
                        }
                    }
                }
            }

"I want to edit the state on a property within the model but the model in this scope isn't bindable so I can't pass it into the Toggle."

I am not sure if I understand correctly, but does the following code not work?

.navigationDestination(for: FMList.self) { list in
    Text(list.name)
    
    @Bindable var bindableList: FMList = list
    
    Toggle(isOn: $lbindableList.isFavorite) {
        Label("Favorite", systemImage: IconConstants.starIcon)
    }
}

" I am filtering with computed properties because I can't do this filter within the Query predicate. The following gave me a compiler error because the ownership.user wasn't a constant value."

If you meant that the predicate is dynamic and relies on a variable, you will need to pass the variable to FMListView, and then set up the Query in the FMListView.init. For a code example, see TripListView in the SwiftData version of the Adopting SwiftData for a Core Data app sample.

If you meant that #Precicate doesn't handle your enum correctly, try to set it up in the following way:

let userRawValue = Ownership.user
let predicate = #Predicate<FMList> {
	$0.ownership.rawValue == userRawValue
}

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

navigationDestination with computed properties from SwiftData queries
 
 
Q