Field Delegates
Sometimes you don't want the whole document — just one field, read and written like an ordinary Kotlin property. Field delegates give you that without giving up typed, reactive storage.
class NoteEditor {
private val note = Documents.document<Note>("note-1")
var done: Boolean by note.field(Note::done, default = false)
val doneFlow: Flow<Boolean> = note.fieldFlow(Note::done, default = false)
}
field(prop, default)
field(prop, default) returns a ReadWriteProperty backed by a single
decomposed key. Reading it returns default if the field was never set; writing it
updates only that field's key — nothing else about the document is touched — and emits on the
document's flow() too:
editor.done = true // writes only the "done" field's key
println(editor.done) // reads only that key
Why the caller supplies default
A field's declared default isn't recoverable from a KProperty at runtime, so
field() and fieldFlow() both take default explicitly —
there's no reflection-based way to ask "what was the default value of this property in the data
class?" once you're holding a bare property reference.
fieldFlow(prop, default)
Emits the current field value (or default, if never set) on collection, then a
new value each time that field changes. A change to a sibling field stays quiet:
note.fieldFlow(Note::done, default = false).collect { done ->
checkbox.setChecked(done)
}
Not inside a class with a delegate? Use update(prop, value)
For a one-off field write with no delegate to declare, plain
note.update(Note::done, true) does the same single-key write directly — see
Read & Write. It's the non-delegate sibling to
field(), for code that doesn't own a var-backed property.
When to reach for this
Field delegates suit settings-style usage — a screen with a handful of independent toggles or values, each bound directly to a property, with no need to read or write the rest of the document. See Settings & Preferences for a fuller example.