Is this a documentation bug? It says to not delay ...
# compose
m
Is this a documentation bug? It says to not delay updating the textfield when the value changes. But then the example does exactly that. Maybe there should be a comment explaining that this is what not to do? https://developer.android.com/jetpack/compose/text#state-mgmt
1
s
Which example are you referring to?
m
Copy code
Do not delay making updates to the state: When you callonValueChange, update your TextField synchronously and immediately:
s
Yes, but which example is it that “does exactly that” in the compose text documentation that you linked?
m
The example directly following that colon
Copy code
class SignUpViewModel(private val userRepository: UserRepository) : ViewModel() {
   fun updateUsername(input: String) {
        viewModelScope.launch {
            // async operation
            val isUsernameAvailable = userRepository.isUsernameAvailable(input)
            // ...
            if (!isUsernameAvailable) {
                // modify error state
            }
           username.value = input
       }
   }
}
Shouldn’t it be:
Copy code
class SignUpViewModel(private val userRepository: UserRepository) : ViewModel() {
   fun updateUsername(input: String) {
        username.value = input
        viewModelScope.launch {
            // async operation
            val isUsernameAvailable = userRepository.isUsernameAvailable(input)
            // ...
            if (!isUsernameAvailable) {
                // modify error state
            }
       }
   }
}
s
Aha I see now, yes this is odd. On one had, right above this it does say “Do not delay” so it may be that they are giving this as an example of how not to do it? Regardless I do agree that this is not clear. I’d create a bug report for the documentation and see what they respond with.
a
viewModelScope
uses
Dispatchers.Main.immediate
, which will run the job immediately and synchronously if it's already on main thread.
m
isUsernameAvailable
takes time though, and who knows on which thread
a
Read your second reply again.
And all callbacks in compose are run on main thread.
m
Sorry, I don’t understand. If
isUsernameAvailable
takes ages, how can it possibly set the value immediately?
s
userRepository.isUsernameAvailable may switch dispatcher to say IO For example though, and this function will be waiting for that response to come back before it sets
username.value
. I feel like I am also missing smth here.
m
Even if it doesn’t switch dispatcher, it still takes potentially a duration longer than “immediate”.
s
If it doesn’t switch dispatcher, then it would work synchronously as it should, since it’s using
Dispatchers.main.immediate
, it’s just that then it’d make the UI hang as far as I understand at least.
m
It says
synchronously and immediately
so that still wouldn’t comply
l
Wouldn't it make more sense to have the username update immediately, with some sort of method that asynchronously checks for error state? (bonus points for observing the username value and mapping it to potential error state). If the check takes some amount of time, such as when my phone has an sd card, or there's a lot of usernames taken, you don't want to slow down the text field's responsiveness.
e
Another issue with not updating the state immediately is that the
TextField
internal state can get messed up and start showing incorrect values / treatment because of how it interacts with the IME
a
Ok, I didn't notice the async operation comment. I guess that's an example of bad pattern.
c
Filed a bug? I'll star 🌠
a
This doc is fixed now. TY for flagging and sorry for the confusion🙏
c
we did it!
e
@Ale Stamato the link in the note that should go to Effective state management for TextField in Compose instead goes to kotlinx StateFlow documentation