Home > Enterprise >  SwiftUI Loading Data
SwiftUI Loading Data

Time:11-16

I am trying to load data from an ObservableObject class when I present a SwiftUI view but I get the following error code: "Cannot use instance member 'documentID' within property initializer; property initializers run before 'self' is available"

Class with the data querying:

class ItemDataDelegate: ObservableObject {
    @Published var serviceContentLoaded = Bool()
    @Published var SelectedCategory: String?
    @Published var SelectedDocumentID: String?
    
    init(SelectedCategory: String, SelectedDocumentID: String){
        self.getSelectedContentData(Category: SelectedCategory, DocumentID: SelectedDocumentID) {
            self.getSelectedCompanyData(CUID: ContentData[indexPath.row].CompanyID) {
                print("data query completed")
            }
        }
    }
}

Here is the View that I want to present when the data from the previous code is called and completed:

The error I mentioned above is shown on the @StateObject var itemDataDelegate = ItemDataDelegate(SelectedCategory: selectedCategory, SelectedDocumentID: documentID) line of code.

struct DetailView: View {
    @Binding var documentID: String
    @Binding var selectedCategory: String
    @StateObject var itemDataDelegate = ItemDataDelegate(SelectedCategory: selectedCategory, SelectedDocumentID: documentID)
    @State private var showSheet = false
    @Environment(\.presentationMode) var mode: Binding<PresentationMode>
    
    var image: UIImage
    var companyName: String
    var cartActive: Bool
    
    var body: some View {
        return ZStack {
            switch itemDataDelegate.serviceContentLoaded {
                case true:
                    ContentView()
                case false:
                    LoadingView()
            }
        }
        .navigationBarHidden(true)
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .edgesIgnoringSafeArea(.all)
    }
}

CodePudding user response:

Since you need to use one of the passed-in parameters in the initialization of the @StateObject, you'll have to write a custom init for your View. Using your current code, it would look something like this:

struct DetailView: View {
    @Binding var documentID: String
    @Binding var selectedCategory: String
    @StateObject var itemDataDelegate : ItemDataDelegate
    @State private var showSheet = false
    @Environment(\.presentationMode) var mode: Binding<PresentationMode>
    
    var image: UIImage
    var companyName: String
    var cartActive: Bool
    
    init(documentID: Binding<String>, selectedCategory: Binding<String>, image: UIImage, companyName: String, cartActive: Bool) {
        _documentID = documentID
        _selectedCategory = selectedCategory
        self.image = image
        self.companyName = companyName
        self.cartActive = cartActive
        _itemDataDelegate = StateObject(wrappedValue: ItemDataDelegate(SelectedCategory: selectedCategory.wrappedValue, SelectedDocumentID: documentID.wrappedValue))
    }
    
    var body: some View {
        return ZStack {
            switch itemDataDelegate.serviceContentLoaded {
                case true:
                    ContentView()
                case false:
                    LoadingView()
            }
        }
        .navigationBarHidden(true)
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .edgesIgnoringSafeArea(.all)
    }
}
  • Related