@ObservedRealmObject vs. cancel

I started using @observedrealmObject and see that it automatically updates the realm.

Now this is great in certain instances, but supposed I want to add a cancel?

Do I NOT used @ObservedRealmObject? What is the proper approach in the cancel ability scenario.

Thank you

Hi @James_Cicenia , what do you mean you want to cancel.
Do you want to use @ObservedRealmObject as a draft object and only add it to the database when you want to, or maybe you want to revert any changes to the object on the database “canceling” all the previous write to that object?

Either scenario would work. I want a usual, “add/edit” / “cancel” type pattern.

Unfortunately you cannot use @ObservedRealmObject as a draft object, you can instead use @StateRealmObject as an unmanaged object and then persist it into the database when is ready.


Are you sure… it seems as though @StateRealmObject is also writing the database immediately.
Is there some global piece I am missing?

There’s no global piece, can you show us your code? Or at least how you’re instantiating the @StateRealmObject?

Maybe I am doing it wrong. I instantiate a company object from querying my Realm in my ModelObject. Now I have a form where I reference my

@StateRealmObject ModelObject.

So the text field would bind to:


Any change in the text field seems to immediately update the data.

would love to see a best practice sample pattern for using Realm/Combine with Save/Cancel functionality. Maybe use UNREALM instead?

In my View:

@StateObject var companyInfoPreferenceVM = CompanyInfoPreferenceViewModel()

companyInfoPreferenceVM.company = iDataModel.company ?? Company()

How I setup the company in the iDataModel object:

public var company: Company?
func setUpDataModelCompany(_ loginView: LoginView) → Bool {
guard let user = app.currentUser else {return false}
self.user = user
let configuration = user.configuration(partitionValue: “user=(user.id)”)
let realm = try! Realm(configuration: configuration)
if let companyId = try? ObjectId(string: AltoProUserDefaults.companyObjectId) {
guard let company = realm.object(ofType: Company.self, forPrimaryKey: companyId) else {
self.showMessage(“Company Not queryable by primary key”, loginView.$loginVM.showToastMessage, loginView.$loginVM.showToast)
return false
self.company = company
refreshCustomData(loginView) {
loginView.loginVM.showWaitingView = false
return true
return false

Now back to my View:

textFieldView($companyInfoPreferenceVM.company.name ?? “”, “Company Name”, .companyName, .next, maxChar: 60, tAuto: .words)

This immediately writes to the database!


@objcMembers public class Company: Object, ObjectKeyIdentifiable {
@Persisted public var name: String?

Why is it syncing immediately?
@Diana_Maria_Perez_Af @Jason_Flax

If iDataModel.company is managed by the Realm (which based on your code, it is)– then assigning it to companyInfoPreferenceVM.company means that companyInfoPreferenceVM.company is now the same reference to the company that you had read from the Realm. So when you bind the name of that company to the textField, it’s going to write directly to the Realm that the company came from.

What you would want here would be the reverse of what you are doing– instead of assigning iDataModel.company to the companyInfoPreferenceVM.company, once you are ready to “save” the “draft data”, you can either:

  • assign the fields you so choose to the iDataModel.company object in a write transaction, or
  • add the draft company to the Realm as an update for the same primary key

What is the proper way to create a draft company that is not realm persisted? Is there some helper method or I have to create a method? Thanks, but still don’t understand why it would sync to the database vs. just locally until transacted.

self.company = Company(value: company) had the same issue.

I would prefer not to have vars linked to textfield.


The simplest way would be (in your view):
@StateRealmObject var company = Company()

but that is blank… I want a copy so I guess it is roll my own

This is the current solution to this issue: