# Input validation in Jetpack Compose

DevFeed: [Input validation in Jetpack Compose](<https://devfeed.tech/articles/input-validation-in-jetpack-compose-25897.md>)

Original publisher: [Read original article](<https://proandroiddev.com/input-validation-in-jetpack-compose-e99c18b44fe3?source=rss-56174fa84bcc------2>)

Author: Denys Rudenko

Published: 2021-08-22T16:42:02Z

Content type: tutorial

Language: en

Sources: [Stories by Denis Rudenko on Medium](<https://devfeed.tech/sources/stories-by-denis-rudenko-on-medium.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [Dagger](<https://devfeed.tech/topics/dagger.md>), [Processes](<https://devfeed.tech/topics/processes.md>), [User experience (UX)](<https://devfeed.tech/topics/ux.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [androiddevweekly](<https://devfeed.tech/tags/androiddevweekly.md>), [dagger](<https://devfeed.tech/tags/dagger.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [savedstatehandle](<https://devfeed.tech/tags/savedstatehandle.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [ux](<https://devfeed.tech/tags/ux.md>), [validation](<https://devfeed.tech/tags/validation.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

## AI overview

This tutorial demonstrates manual and automatic input validation in Jetpack Compose. It uses composables, ViewModels, Dagger Hilt, StateFlow, and savedStateHandle to preserve input state after process death, validate fields, control button state, and emit success or error events. It also discusses restoring focus and improving keyboard-related user experience.

## Source excerpt

This post will not only focus on manual & auto validation of TextField inputs, but also on how to provide a nice UX by handling process death, including highlighting the last focused field upon restoration. https://medium.com/media/7d776a0ec6ff89810e194adf54680973/hrefSetup We'll use composables, viewModels & Dagger Hilt in these samples. Part 1: InputWrapper Let's create a wrapper for inputs, so it can contain both input value and errorId, if there is a validation error. Class is parcelable, so we can save it inside savedStateHandle later. https://medium.com/media/6c74ba5b4f958d63646a819643b45620/hrefPart 2: ViewModel (simplified version)https://medium.com/media/39bf975a63461cd00f68b8360c6a8f6b/href We're getting a stateFlow from the savedStateHandle using .getStateFlow extension. Using savedStateHandle here allows us to retain the latest data after process death happens. You can also use getLiveData, it's a matter of personal preferences unless you plan to perform observable.switchMap/flatMapLatest type of operations, since there is a subtle difference between stateFlow & liveData in such scenarios described here & change proposal created. areInputsValid stateFlow is combining name & creditCardNumber flows into a single one. The results it returns depend on whether input fields are valid or not. It's invoked whenever there is new emition to name or creditCardNumber flows. We'll use it's value to control buttons enabled/disabled state in our composable. _events will be used for one time events emission to the view layer. ScreenEvent is a sealed class representing all of our one time events. onNameEntered & onCardNumberEntered will be invoked when user enters symbols inside the TextField. We find out whether the input is valid by using an InputValidator object. It's returning either a string resource id containing error message, or a null. Latter means that input is valid. We store the new value & errorId using: https://medium.com/media/d9ad9c61328481f3318c143e6daf3