Reputation: 2862
I am developing an android app, and my use case requires validating some user's inputs.
As an example, I have depth value (in reality, it has more than 20 inputs) which should be something between 3 and 100 inclusive. and since it is an info provided by the user to do some calculation, I have a Dialog for that, my questions is: how to validate the input in real time using the view model (is it the correct way to validate the input?). My initial naive solution was to create a helper class that validate the TextInput value
fun validateDepth(depth: String): Boolean {
return depth.isNotBlank() && depth.toIntOrNull() != null && depth.toInt() in 3..100
}
and then
DepthPicker(
value = depthValue,
onValueChange = onDepthValueChange,
validator = DepthValidator::validateDepth // <---- HERE: I dind't like this part
)
But I didn't like the fact that the UI is doing the validation and not the ViewModel, this is making it hard to test. and the depth value must be validated before sending it to the repository.
my dialog is a simple composable
Dialog(onDismissRequest = onDismissRequest) {
...
TextField(...)
}
UiState
data class UiState(val depth: Int?)
ViewModel
@HiltViewModel
class DepthViewModel @Inject constructor(
private val depthRepository: DepthRepository,
) : ViewModel() {
private val _uiState = MutableStateFlow(DepthUiState())
val uiState = _uiState.AsStateFlow()
fun updateDepth(depth: Int?) = _uiState.update { it.copy(depth = depth) }
....
}
TL;DR: how/where to validate user's input on a dialog with a text field while typing? NOTE if the user already entered a valid value, and then decided to change it, click on edit, change it to a non valid and then click cancel, then the old valid value must be shown.
Upvotes: 0
Views: 924
Reputation: 66759
You can do it inside domain layer using a UseCase or Interactor class which only consists of non-Android classes, objects or functions that makes it easy to unit test or move to another ViewModel when required. UseCases are single responsiblity classes that handle business logic as stated in The Clean Architecture by Robert C. Martin (Uncle Bob)
Use Cases The software in this layer contains application specific business rules. It encapsulates and implements all of the use cases of the system. These use cases orchestrate the flow of data to and from the entities, and direct those entities to use their enterprise wide business rules to achieve the goals of the use case.
We do not expect changes in this layer to affect the entities. We also do not expect this layer to be affected by changes to externalities such as the database, the UI, or any of the common frameworks. This layer is isolated from such concerns.
And official Android document for Android what's domain layer and how you can use it with Jetpack Compose. You can check out JetNews app or ioshed app for more details either.
And how that circle block is translated to Android can be viewed as in this image.
https://developer.android.com/topic/architecture/domain-layer
Upvotes: 0