I have viewmodel and view i have return some API logic in viewmodel and getting one dictionary after some logic..i want to access that dictionary value from view for ex.
viewmodel.someDic
but for now every-time i am getting empty dic.
class Viewmodel: ObservableObject {
@Published private var poductDetails:[String:ProductDetail] = [:]
func createItems(data: ProductRootClass) {
var productDetils = [String: SelectedProductDetail](){
//some logic
productDetils // with some object
self.poductDetails = productDetils
}
}
}
struct View: View {
@StateObject var viewModel: ViewModel
var body: some View {
VStack(alignment: .leading) {
Text("\(viewModel.poductDetails)")
}
.onAppear(perform: {
print("\(viewModel.poductDetails)")
})
}
}
I want to access this dictionary from view.
I tried accessing by returning productDetils from any function but get empty everytime.
may i know the way to access property from viewmodel to view?
CodePudding user response:
You need a class conforming to ObservableObject
and a property marked as @Published
class ViewModel : ObservableObject {
@Published var productDetails = [String:ProductDetail]()
func createItems(data: ProductRootClass) {
var productDetils = [String: SelectedProductDetail]()
//some logic
productDetils // with some object
self.productDetails = productDetils
}
}
Whenever the property is modified the view will be updated.
In the view create an instance and declare it as @StateObject
struct ContentView: View {
@StateObject var viewModel = ViewModel()
var body: some View {
VStack(alignment: .leading) {
ForEach(viewModel.productDetails.keys.sorted(), id: \.self) { key in
Text("\(viewModel.poductDetails[key]["someOtherKey"] as! String)")
}
}
}
}
I would prefer an array as model, it's easier to access
CodePudding user response:
You need to get rid of the view model and make a proper model.
class Model: ObservableObject {
@Published private var productDetails:[ProductDetail] = []
}
struct ProductDetail: Identifiable {
let id = UUID()
var title: String
}
Now you can do ForEach(model.productDetails)
CodePudding user response:
You can make your viewModel as a Singleton.
class ViewModel : ObservableObject {
static let viewModelSingleton = ViewModel()
@Published var productDetails = [String : ProductDetail]()
\\API logic}
Access this viewModel Singleton in the view
struct view : View {
@ObservedObject var viewModelObject = ViewModel.viewModelSingleton
var body: some View {
VStack(alignment: .leading) {
Text("\(viewModelObject.productDetails)")
}
}}