Tristan N
Tristan N

Reputation: 35

Picker selection mismatch with decoded Json river data

I am building a swift application and am trying to have a selection of options in a menu picker for different rivers. Currently, the issue I am having is that when selecting a different river for the first time after opening the app, it gets the river data for the default index (0) of the picker option.

For example, when I open the app, Howes Valley is the default and it finds the river heights for this correctly. However If I pick another option, it uses the Howes valley id "212021", instead of the one selected.

 let rivers: [River] = [
        River(id: "212021", name: "McDonald River @ Howes Valley"),
        River(id: "212461", name: "Hawkesbury River @ Leetsvale"),
        River(id: "212290", name: "Colo River @ Upper Colo")
    ]

**I have tried to modify my menu picker logic to select the index of the menu picker, but still having the issue. Here is the code for my River Data menu picker **

GroupBox(label: Label("River Data", systemImage: "waveform.path.ecg")
                .font(.title)
                .foregroundColor(.blue)
                .padding(.bottom, 8)
            ) {
                
                Picker(selection: $selectedRiverIndex, label: Text("Select a river")) {
                    ForEach(0..<rivers.count, id: \.self) { index in
                        Text(rivers[index].name)
                    }
                }
                .pickerStyle(MenuPickerStyle())
                .onChange(of: selectedRiverIndex) { newIndex, _ in
                    isLoading = true // Show loading indicator
                    Task {
                        let newRiverIndex = newIndex
                        await riverModel.fetchRiverHeightData(for: rivers[newRiverIndex].id)
                        isLoading = false // Hide loading indicator after data is fetched
                    }
                }
              
              // River data details view
                VStack(alignment: .leading, spacing: 8) {
                    ForEach(riverModel.riverData, id: \.time) { riverValue in
                        VStack(alignment: .leading) {
                            if let convertedDate = convertDateString(riverValue.time) {
                                Text("\(riverValue.v)m")
                                    .font(.headline)
                                Text("Last Updated:")
                                    .font(.subheadline)
                                    .foregroundColor(.secondary)
                                Text("\(convertedDate.date) at \(convertedDate.time)")
                                    .font(.subheadline)
                            }
                        }
                        .padding(.vertical, 4)
                    }
                }
            }`

**
Here is the code for default when opening the app:**
 // Fetch river details and river data when the view appears
`        
.onAppear {
            Task {
                let selectedRiverID = "212021" // Set the initial selected river ID
                await riverModel.fetchRiverHeightData(for: selectedRiverID)
                isLoading = false // Hide loading indicator after data is fetched
            }
            
        }
`

Upvotes: 0

Views: 53

Answers (1)

Tristan N
Tristan N

Reputation: 35

Thanks @workingdog!

It turned out that I needed to add newIndex in the onChange modifier:

    .onChange(of: selectedRiverIndex) { oldIndex, newIndex in
        isLoading = true
        Task {
            let newRiverIndex = newIndex
            await riverModel.fetchRiverHeightData(for: rivers[newRiverIndex].id)
            isLoading = false
        }
    }

Upvotes: -1

Related Questions