The point is that after successfully adding a record to the database (when I tap confirm button), the view should be closed. The problem is that it does not close after adding, .onReceive does not triggered, although the publisher PassthroughSubject sends a new value. There is one thing: the view will close if an alert was triggered before clicking the confirm button (for example, when not all fields are filled in, a warning is displayed)
Also properties viewModel.name and viewModel.name (for TextField's) after adding a record become equal to empty strings, although I do not explicitly assign such a value to them anywhere in the code (as if a new instance of the view model is created where such default values are)
View:
struct AddChallengeView: View {
@Environment(\.presentationMode) var presentationMode
@ObservedObject var viewModel = AddChallengeViewModel()
var body: some View {
Form{
Section(header: Text("Name")){
TextField("Type challenge name", text: $viewModel.name) //viewModel.name == "" after new record added
}
Section(header: Text("Description")){
TextEditor(text: $viewModel.description) //viewModel.description == "" after new record added
}
//...
Section{
Button(action: { viewModel.addChallenge()}){
HStack{
Spacer()
Text("Submit").bold()
Spacer()
}
}
}
}.alert(isPresented: $viewModel.showErrorAlert){
Alert(title: Text("Please, set all values!"))
}
.onReceive(viewModel.viewDismissalModePublisher) { shouldDismiss in
print("new value received") //not printed
if shouldDismiss {
self.presentationMode.wrappedValue.dismiss()
}
}
}
}
ViewModel:
class AddChallengeViewModel: ObservableObject{
var viewDismissalModePublisher = PassthroughSubject<Bool, Never>()
private var shouldDismissView = false {
print("sending new value") //printed
didSet {
viewDismissalModePublisher.send(shouldDismissView)
}
}
@Published var showErrorAlert = false
@Published var name = ""
@Published var description = ""
//...
func addChallenge () {
//...
if (name != "" && description != "" && grounds.count != 0){
Firestore.firestore().collection("users").document(Auth.auth().currentUser!.uid).collection("challenges").addDocument(data: [
"name": "\(name)",
"description": "\(description)",
"grounds": grounds
]) { err in
if let err = err {
print("Error adding document: \(err)")
} else {
print("setting new value") //printed
self.shouldDismissView = true
}
}
} else {
showErrorAlert.toggle()
}
}
}
UPDATE: I found a solution. We need to replace @ObservedObject var viewModel = AddChallengeViewModel() with @StateObject var viewModel = AddChallengeViewModel() in AddChallengeView but why does it work?