Home > Software design >  SwiftUI nested API JSON call
SwiftUI nested API JSON call

Time:06-30

Hey there I'm working on a little SwiftUI Project with some data, hosted by my own local network.

When the view appears, I'm calling the QuestionApiCall().getAllQuestions method which returns an Array of Question Objects. So far so good. In every Question Object inside of the returned Array, there is a variable called senderId. This variable is necessary for calling another Method: UserByApiCall(id: senderId).getUserById for getting the name of the User which asked the Question.

My idea was:

ScrollView(showsIndicators: false) {
    VStack {
       ForEach(questions) {question in
           QuestionView(name: ?, content: question.content, creationTime: question.creation)
       }
    }
}
.onAppear() {
    QuestionApiCall().getAllQuestions { (questions) in
        self.questions = questions
}

Displaying the Question works properly but I don't know how to display their names, which can only displayed when calling the UserByApiCall(id: senderId).getUserById every time it loops threw the questions-Array with the specific senderId.

In theory I need to execute the UserByApiCall(id: senderId).getUserById every time question gets looped in the ForEach-Loop with the question.senderId for getting the User Object for every Question to display their names.

I really got no Idea how to make it or where to call it. I can't just edit the Api and their methods because its an exercise from my Internship.

CodePudding user response:

If you really can´t change the API move the responsibility to call the name API to your QuestionView.

As you didn´t include your QuestionView I need to make a few asumptions about it.

Your name var should look like this:

@State private var name: String = ""

In the .onApear of QuestionView add your function to call the name:

.onApear{
    if name == ""{
        UserByApiCall(id: senderId).getUserById{[weak self] name in
            self?.name = name
        }
    }
}

And finally make your VStack a LazyVStack:

LazyVStack {
   ForEach(questions) {question in
       QuestionView(name: ?, content: question.content, creationTime: question.creation)
   }
}

The LazyVstack will ensure, that not all elements are loaded at once.

  • Related