1

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)
    }
}
3
  • Create the object in the parent view and inject it instead. Commented Nov 15, 2021 at 7:40
  • 1
    It seems you are having the similar issue mentioned in this stackoverflow thread. Can you try out the answer mentioned in the accepted answer? Commented Nov 15, 2021 at 15:48
  • @Prabir yup, your answer has the same solution to the one jnpdx posted below. Thank you as well! Commented Nov 15, 2021 at 19:34

1 Answer 1

2

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)
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

You are amazing. Thank you so much 😅

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.