houman.sanati
houman.sanati

Reputation: 1074

binding to a suspended function in android

I want to bind a button click to a suspended function inside viewmodel.

this is my code:

RegistrationActivityViewModel.kt

    suspend fun register() {
        if (validateFields()) {
            val result = SourceplusplusApiService.invoke().registerUser(username.value!!, email.value!!, password.value!!).await()
            isRegistrationCompleted.value = getResultValue(result)
        }
    }

activity_registration.xml

<Button
          android:text="Register"
          android:onClick="@{()->viewmodel.register()}"
          android:textSize="16sp" />

i get a databinding error that says ActivityRegistrationBindingImpl not generated. after searching a lot i realized that when i remove the suspend keyword and comment the code inside, it works fine but it has to be a suspended function.

Does anyone know how to fix it?

Upvotes: 3

Views: 5537

Answers (1)

CommonsWare
CommonsWare

Reputation: 1007276

You cannot data bind to a suspend function, and IMHO a viewmodel should not be exposing a suspend function in the first place. I recommend:

Step #1: Remove the suspend keyword from register()

Step #2: Rewrite register() to run your code in a suitable coroutine scope, so any suspend functions that it calls are handled properly:

fun register() {
    viewModelScope.launch(Dispatchers.Main) {
        if (validateFields()) {
            val result = SourceplusplusApiService.invoke().registerUser(username.value!!, email.value!!, password.value!!).await()
            isRegistrationCompleted.value = getResultValue(result)
        }
    }
}

Here, I am using the viewModelScope option provided by androidx.lifecycle:lifecycle-viewmodel-ktx version 2.1.0-alpha01 and newer. Alternatively, manage your own coroutine scope. Dispatchers.Main will ensure that any results of that work is available to you on the Android main application thread.

Now, your data binding expression can refer to register(), while you still have a coroutine scope for calling downstream suspend functions.

Upvotes: 7

Related Questions