Reputation: 5400
I have simple viewModel
:
final class EmployeeListViewModel: ObservableObject {
@Published var list = [Employee]()
init() {
// some request
self.list = [Employee, Employee]
}
}
And have a view
:
struct EmployeeView: View {
@ObservedObject var viewModel = EmployeeListViewModel()
@State private var showContents: [Bool] = Array(repeating: false, count: viewModel.list.count)// <- error throws here
var body: some View {
GeometryReader { fullView in
ScrollView {
VStack(spacing: 40) {
ForEach(self.viewModel.list) { employee in
Text(employee.firstName).foregroundColor(.black)
}
}
}
}
}
}
Error text:
Cannot use instance member 'viewModel' within property initializer; property initializers run before 'self' is available
I tried change it with init
:
struct EmployeeView: View {
@ObservedObject var viewModel = EmployeeListViewModel()
@State private var showContents: [Bool]
init() {
_showContents = State(initialValue: Array(repeating: false, count: viewModel.list.count)) // <- error
}
var body: some View {
GeometryReader { fullView in
ScrollView {
VStack(spacing: 40) {
ForEach(self.viewModel.list) { employee in
Text(employee.firstName).foregroundColor(.black)
}
}
}
}
}
}
But it also throws error:
'self' used before all stored properties are initialized
this throws on I call viewModel
on init()
How to solve it? @State i use for card view. There I simplified views for easy understand.
Upvotes: 3
Views: 1054
Reputation: 51920
First initialise the state variable to an empty array
@State private var showContents: [Bool] = []
then set it in the init
init() {
showContents = Array(repeating: false, count: viewModel.list.count)
}
You shouldn't initialise the view model property in the view but rather use dependency injection
init(viewModel: EmployeeListViewModel) {
self.viewModel = viewModel
showContents = Array(repeating: false, count: viewModel.list.count)
}
Upvotes: 1
Reputation: 257703
Here is possible solution
struct EmployeeView: View {
@ObservedObject var viewModel: EmployeeListViewModel // << declare
@State private var showContents: [Bool] // << declare
init() {
let vm = EmployeeListViewModel() // create here !!
// initialize both below
self.viewModel = vm
self._showContents = State(initialValue: Array(repeating: false,
count: vm.list.count))
}
Upvotes: 0