I'm trying to follow Google's clean architecture guidelines.
I have a navigation subgraph with multiple pages corresponding to stages of filling a form.
Each page has it's own viewModel.
On the last screen I need to send data from the form to app's data layer which sends it to server.
How should I share the form object between viewModels?
I see such options here:
Form
model and FormRepository
in app's data layer and inject it to viewModels. I don't like it because knowledge about form is not exclusive for feature module anymore and appears in data layer, though it is basically a UI stateFormHolder
singleton in feature module, that is injected to all VMs. I'm not sure about it because I'm trying to follow architecture guidelines.What should I do?
How to do it:
Create a FormViewModel
scoped to the navigation subgraph (not individual screens).
Each screen still uses its own ScreenViewModel
, but it reads from/writes to the FormViewModel
.
Validation and retrieval logic stay in screen ViewModels.
Only FormViewModel
talks to domain layer when submitting the final form.
// Shared ViewModel scoped to the subgraph
class FormViewModel @Inject constructor() : ViewModel() {
var formState = mutableStateOf(FormData())
fun updatePart1(data: Part1) { formState.value = formState.value.copy(part1 = data) }
fun submitForm() { /* call useCase to submit */ }
}
// Each screen has its own logic
class Step1ViewModel @Inject constructor(
private val formViewModel: FormViewModel // Injected via navGraphViewModels()
) : ViewModel() {
fun onNext(input: Input) {
// validate and update shared state
formViewModel.updatePart1(convert(input))
}
}
Navigation-Scoped ViewModel:
val formViewModel: FormViewModel by navGraphViewModels(R.id.formGraph) {
defaultViewModelProviderFactory
}