What i’m trying to achieve: I interact with a row in a list, this triggers an API
call to retrieve data using some ID
, and then navigate to the new view with said data. How do I do this?
Typically, when navigating to a new view, I would do something like this:
@StateObject var viewModel = MyViewModelClass()
...
List {
ForEach(viewModel.items, id: .self) { item in
NavigationLink {
ItemDetailView(item: item)
} label: {
ItemView(item: item)
}
}
}
This approach works fine when i have the data at hand for the subview as well. But how can I do the same when the subview needs to fetch data based on the selected row. i.e. I need to pass an itemID
to be able to fetch data for the new view. I’ve tried the following:
View:
List {
ForEach(viewModel.items, id: .self) { item in
Button {
viewModel.fetchItems(itemID: item.ID)
} label: {
ItemView(item: item)
}
.navigationDestination(isPresented: $viewModel.readyToNavigate) {
ItemDetailView()
}
}
}
ViewModel:
@Published var items: [Item] = []
@Published var readyToNavigate: Bool = false
init() {
fetchItems()
}
func fetchItems(itemID: String) {
Task {
do {
let result = try await APIService().fetchItem(itemID: itemID)
items.append(contentsOf: result)
readyToNavigate = true
} catch {
self.error = error
}
}
}
This does not work. I just navigate to the detail view without any data. I suspect i’m going the wrong way, and my MVVM practice is incorrect too. I am trying to use the same viewModel for both views. Is this acceptable or should they be separate? And if they are, how does the 2nd vm, get the ID? Any help is appreciated, thanks!