SwiftUI picker didn't update

Viewed 137

I tried to build a form that contained multiple picker. The first picker will show the existing data. The second picker will get the data from API according to the selection from first picker. However, when I open the form, the first picker work but the second picker display nothing. Even I select other selection from first picker, I can get the data but the second picker didn't update as my expectation. So the main question is how to make the second picker get data since there is a default selection in first picker. And what is the problem that cause the second picker no update after I make a selection in first picker

struct addBooking : View {
    @State var shops = ShopJSON.shared.shops //existing data
    @State var selectedShopIndex = 0
    @State var selectedOutletIndex = 0
    @ObservedObject var bookingOutletJSON = BookingOutletJSON()
    
    var body: some View {
        NavigationView{
            Form {
                Picker(selection: $selectedShopIndex, label: Text("Select Shop")) {
                    ForEach(0 ..< shops.count) {
                        Text(self.shops[$0].name!)
                    }
                }
                .onChange(of: selectedShopIndex, perform: { (value) in
                    print("Shop changed")
                    bookingOutletJSON.getOutlet(selectedShopId: shops[value].shopID!)
                })
                Picker(selection: $selectedOutletIndex, label: Text("Select Outlet")){
                    ForEach(0 ..< bookingOutletJSON.outlets.count) {
                        Text(self.bookingOutletJSON.outlets[$0].location!)
                    }
                }
                if bookingOutletJSON.outlets.count != 0 {
                    Text("\(bookingOutletJSON.outlets[0].location!)")
                }
class BookingOutletJSON : ObservableObject{
    @Published var outlets = [BookingOutlets]()
    init() {
        
    }
    func getOutlet(selectedShopId : Int){
        //API get data
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
          guard let data = data else {
            print(String(describing: error))
            return
          }
            if let decodedOutlet = try? JSONDecoder().decode(OutletModal.self, from: data) {
                DispatchQueue.main.async {
                    self.outlets = decodedOutlet.outlets!
                    print(self.outlets)
                    print("Outlet updated")
                }
            } else {
                print("Invalid response from server")
            }
        }

        task.resume()
    }
}
1 Answers

Try with another ForEach constructor

Picker(selection: $selectedOutletIndex, label: Text("Select Outlet")){
    ForEach(bookingOutletJSON.outlets.indices, id: \.self) {
        Text(self.bookingOutletJSON.outlets[$0].location!)
    }
}
Related