[Office Hours] Mutability of Medication List #104
-
In what area do you have a technical challenge?Xcode, Simulator & Previews DescriptionUpon progressing to the "Add Medication" sheet, I am having difficulty updating the given patient's medication list upon prescribing a new medication. It appears the root of the issue lies in the mutability of the patient variable- and passing in the patient as Binding through different view in the NavigationLink. Please see snippets of code from each level of the navigation stack. @Observable
class PatientList: ObservableObject { // used @published and made PatientList an ObservableObject
@Published var patients: [Patient] = [
Patient(firstName: "John", lastName: "Doe", DOB: DOB(DOB: DateComponents(year: 1999, month: 11, day: 8)), height: 200, weight: 75, bloodType: BloodType(typeBlood: "O+"), medications: [Medication1])
]
} struct PatientListView: View {
@ObservedObject var patientList = PatientList()
var body: some View {
NavigationStack {
List($patientList.patients) { $patient in
NavigationLink(value: $patient) {
...
.navigationTitle("All Patients")
.navigationDestination(for: Patient.self) { patient in PatientDetailView(patient: $patient) // error- cannot find $patient in [scope]
struct PatientDetailView: View {
@State private var showAddMedicationView: Bool = false
@Binding var patient: Patient
var body: some View {
...
Button(action: {self.showAddMedicationView.toggle()}) { Text("Add Medication") }
.font(.headline)
.foregroundColor(.white)
.padding()
.background(Color.blue)
.cornerRadius(10)
}
.sheet(isPresented: $showAddMedicationView) {
AddMedicationView(patient: $patient, showAddMedicationView: $showAddMedicationView) // opens add medication sheet
struct AddMedicationView: View {
@Binding var patient: Patient
var body: some View {
...
Button(action: { if checkInput() {
let newMedication = Medication(name: medicationName, dosage: medicationDosage, route: medicationRoute, frequency: medicationFrequency, duration: medicationDuration)
patient.prescribeMedication(med: newMedication) // (error: call can throw- but not marked with try)
self.showAddMedicationView.toggle()
} ReproductionI have been changing @binding and @observable on patient objects just to see what works- so I am now a little lost with what is a standard way to pass in a mutable variable. Expected behaviorPrescribe the medication to the patient- so that upon returning to the detail view, the medication list is updated. Additional contextThank you for the help! Code of Conduct
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Hi @EthanRakutoBell, Thank you for reaching out and asking this question! Let's go through some of the elements step by step. Most of the elements that you are encountering are due to your usage (or rather not usage) of It seems like you are mixing elements between the old way observation in Swift was handled and the new The SwiftUI basics video might also be a great help to understand the fundamentals of SwiftUI and I think it might also be helpful to follow this article to explain to you how you can translate old struct Patient: Hashable, Identifiable {
let id = UUID()
var name: String
}
@Observable
class PatientManager {
var patients: [Patient] = []
} To ensure that you obtain bindable elements from your list, please revisit the usage of Secondly, the mechanism of utilizing a NavigationLink with a value attached to it might make things more complicated than they have to be. struct ContentView: View {
var patientList = PatientManager()
var body: some View {
@Bindable var patientList = patientList
List($patientList.patients) { patientBinding in
NavigationLink(
destination: {
PatientDetailView(patient: patientBinding)
},
label: {
Text(patientBinding.wrappedValue.name)
}
)
}
}
}
struct PatientDetailView: View {
@Binding var patient: Patient
var body: some View {
Text("Detail view for patient: \(patient.name)")
}
} As you can see in the simplified example above, you can easily bind the patientList to an You can always obtain the wrapped value of the Binding property wrapper using the |
Beta Was this translation helpful? Give feedback.
Hi @EthanRakutoBell,
Thank you for reaching out and asking this question!
Let's go through some of the elements step by step. Most of the elements that you are encountering are due to your usage (or rather not usage) of
@Observable
and the usage ofBindings
. Some of these things can be challenging to get started, so let's go through them step-by-step.It seems like you are mixing elements between the old way observation in Swift was handled and the new
@Observable
macro. We would encourage you to use@Observable
, but a lot of examples are out there, and almost all LLMs still output stuff in the old syntax and mechanism. Here is a refresher on@Observable
. The following WWDC video also pro…