Hi Guys, I am trying to run the function into the OnAppear and the function runs correctly but the View does not change when the ViewModel values change.
ViewModel:
View:
ViewModel:
Code Block import SwiftUI class LocationDetailViewModel: ObservableObject { @Published var amenities: [Amenity]? @Published var isLoading: Bool? = true @Published var error: String? func fetchAmenities(dbLocation: DBLocation){ Amenity.fetchAmenites(dbLocation: dbLocation) { [weak self] (locationAmenities, error) in self?.isLoading = false if error == nil{ print("Success!!!!!!!") if let locationAmenities = locationAmenities, locationAmenities.count > 0 { self?.amenities = locationAmenities.map{ $0.amenity } } }else{ print("Error!!!!!!!!!") self?.error = error?.localizedDescription } } } }
View:
Code Block import SwiftUI import SDWebImageSwiftUI import MapKit struct LocationDetailView: View { let dbLocation: DBLocation @State private var isPresentingSaveToCollection: Bool? @State private var isPresentingToast: Bool? @State private var toastText: String? @ObservedObject var locationDetailViewModel = LocationDetailViewModel() let defaultImageUrl: String var body: some View { GeometryReader{ geometry in VStack{ if locationDetailViewModel.isLoading ?? true { VStack(alignment: .center){ InProgressView() }.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height, alignment: .center) }else{ LocationView(dbLocation: dbLocation, defaultImageUrl: defaultImageUrl, isPresentingSaveToCollection: $isPresentingSaveToCollection) .environmentObject(locationDetailViewModel) .padding(.top, geometry.safeAreaInsets.top) .background(SwiftUI.Color( colorLiteral(red: 0.9644473195, green: 0.9684088826, blue: 0.9848803878, alpha: 1))) .edgesIgnoringSafeArea([.top, .horizontal]) } } } .onAppear{ locationDetailViewModel.fetchAmenities(dbLocation: dbLocation) } .navigationBarHidden(true) .fullscreenModal(isShowing: $isPresentingSaveToCollection) { SaveToCollectionView(isPresentingSaveToCollection: $isPresentingSaveToCollection, isPresentingToast: $isPresentingToast, toastText: $toastText) }.toast(isShowing: $isPresentingToast, message: toastText ?? "Undefinded Toast") } }
Try this. Where you initialize the LocationDetailViewModel() in the View, use @StateObject instead of @ObservedObject. Do that whenever the observed object belongs to the view.
To contrast, if you want to share that object among other views (ie it doesn't belong to this View), keep it as an @ObservedObject and create and initialize it outside the view and pass it.
Also, maybe keep the location and model together so it can update. So that all the state information is in the model and spread across the view and model.
To contrast, if you want to share that object among other views (ie it doesn't belong to this View), keep it as an @ObservedObject and create and initialize it outside the view and pass it.
Also, maybe keep the location and model together so it can update. So that all the state information is in the model and spread across the view and model.