Search code examples
swiftuiswiftui-navigationlink

SwiftUI - Navigate to view after retrieving data


So I'm retrieving data from FireStore. I'm retrieving the data successfully. When I tap my search button the first time the data is being downloaded and the new view is pushed. As a result, I get a blank view. But when I go back, hit search again, sure enough I can see my data being presented.

How can I make sure I first have the data I'm searching for THEN navigate to the new view? I've used @State variables etc. But nothing seems to be working. I am using the MVVM approach.

My ViewModel:

class SearchPostsViewModel: ObservableObject {
    var post: [PostModel] = []
 @State var searchCompleted: Bool = false
    func searchPosts(completed: @escaping() -> Void, onError: @escaping(_ errorMessage: String) -> Void) {
            isLoading = true
        API.Post.searchHousesForSale(propertyStatus: propertyStatus, propertyType: propertyType, location: location, noOfBathrooms: noOfBathroomsValue, noOfBedrooms: noOfBedroomsValue, price: Int(price!)) { (post) in
            self.post = post
            print(self.post.count)
            self.isLoading = false
            self.searchCompleted.toggle()
        }
    

    }
    
}

The code that does work, but with the bug:

                    NavigationLink(destination: FilterSearchResults(searchViewModel: self.searchPostsViewModel)
                        .onAppear(perform: {
                            DispatchQueue.main.async {
                                self.createUserRequest()
                            }
                        })
                        )
                      {
                        Text("Search").modifier(UploadButtonModifier())
                    }

Solution

  • Try with the following modified view model

    class SearchPostsViewModel: ObservableObject {
        @Published var post: [PostModel] = []         // << make both published
        @Published var searchCompleted: Bool = false
    
        func searchPosts(completed: @escaping() -> Void, onError: @escaping(_ errorMessage: String) -> Void) {
                isLoading = true
            API.Post.searchHousesForSale(propertyStatus: propertyStatus, propertyType: propertyType, location: location, noOfBathrooms: noOfBathroomsValue, noOfBedrooms: noOfBedroomsValue, price: Int(price!)) { (post) in
                DispatchQueue.main.async {
                   self.post = post           // << update on main queue
                   print(self.post.count)
                   self.isLoading = false
                   self.searchCompleted.toggle()
               }
            }
        }
    }