Samin Jilani
Samin Jilani

Reputation: 155

How to update observableObject class after value is updated by picker - swiftui

I have an ObservableObject class that fetches the remote data based on month and year value. Initially it works fine because I use current month and year values however I want to update and re run the getAttendanceRecord2 when I select some other month from picker. What is the best practice for achieving this?

struct AttendanceRecord: View {
    
    @ObservedObject var item_data: getAttendanceRecord2
    
    let months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November","December"]
    
    init(id: String) {
        self.item_data = getAttendanceRecord2(id: id,month: getMonth(), year: getYear())
    }
    
    var body: some View {
        
        VStack {
            
            Picker(selection: $selectedMonth, label: Text("Months"), content: {
                ForEach(months, id: \.self) {
                    Text($0)
                }
            }).pickerStyle(MenuPickerStyle())
            
            Text("You selected: \(selectedMonth)")
        }
    }
}

Here is my function:

class getAttendanceRecord2: ObservableObject {
    
    @Published var attlist = [EAttendance]()
        
    init(id: String, month: String, year: String) {
        
        let url = URL(string: "http://superteclabs.com/apis2/AttendanceRecord2.php")
        var request = URLRequest(url: url!)
        request.httpMethod = "POST"
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Accept")
        let formdata: Data = "id=\(id)&month=\(month)&year=\(year)".data(using: .utf8)!
        request.httpBody = formdata
        
        URLSession.shared.dataTask(with: request) { (response_data, response, error) in
            guard error == nil else {
                print("Error: error calling POST")
                print(error!)
                return
            }
            guard let data = response_data else {
                print("Error: Did not receive data")
                return
            }
            guard let response = response as? HTTPURLResponse, (200 ..< 299) ~= response.statusCode else {
                print("Error: HTTP request failed")
                return
            }
            
            do {
                
                let decodedData = try JSONDecoder().decode([EAttendance].self, from:data)
                DispatchQueue.main.async {
                    self.attlist = decodedData
                }    
            } catch {
                print("Error: Trying to convert JSON data to string")
                return
            }
        }.resume()
    }  
}

Upvotes: 1

Views: 197

Answers (1)

Asperi
Asperi

Reputation: 258345

It can be done in onChange(of:, like

Picker(selection: $selectedMonth, label: Text("Months"), content: {
    ForEach(months, id: \.self) {
        Text($0)
 }
}).pickerStyle(MenuPickerStyle())
.onChange(of: selectedMonth) { newMonth in           // << here !!
   // process here new selected month as needed
}

Upvotes: 0

Related Questions