Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin coroutine list returning null value

New at development of android apps. I am using kotlin and I am triying to retrieve a list from room database at my viewmodel and make a toast at my fragment when I push a button (codes below). If I push the button once, I get an empty string, but if I push twice, I get the list. How can I do to retrive the list with just one push? Probably I am missing something from coroutines.

Viewmodel code:

var Listado = ""


    fun listaTotal(): String {
        uiScope.launch {
            getTodaListaCompra().forEach{
                Log.i("Listado Compra",Listado )
                Listado = Listado + " " + it
                Log.i("Data",data.value)
                Log.i("Pueba",it)
            }
        }
        return Listado 
    }

Fragment call:

Toast.makeText(application, tabListaCompraViewModel.listaTotal(), Toast.LENGTH_SHORT)
                .show()

Thanks in advance

like image 381
Eaedev Avatar asked Jun 15 '26 13:06

Eaedev


1 Answers

I would suggest using LivaData to observe data:

class MyViewModel : ViewModel() {

    val listado: LiveData<String> = MutableLiveData<String>()

    fun listaTotal() = viewModelScope.launch {
        var localListado = ""
        getTodaListaCompra().forEach{
            localListado = "$localListado $it"
        }
        (listado as MutableLiveData).value = localListado
    }

    // function marked as suspend to suspend a coroutine without blocking the Main Thread
    private suspend fun getTodaListaCompra(): List<String> {
        delay(1000) // simulate request delay
        return listOf("one", "two", "three")
    }
}

In your activity or fragment you can use next methods to instantiate ViewModel class and observe data:

private fun initViewModel() {
    val viewModel = ViewModelProvider(
            this,
            viewModelFactory { MyViewModel() }
    )[MyViewModel::class.java]

    viewModel.listado.observe(this, androidx.lifecycle.Observer { data: String ->
        Toast.makeText(application, data, Toast.LENGTH_SHORT).show()
    })

    viewModel.listaTotal()
}

inline fun <VM : ViewModel> viewModelFactory(crossinline f: () -> VM) = object : ViewModelProvider.Factory {
    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel> create(aClass: Class<T>):T = f() as T
}

Also you may need to import next libraries:

api 'androidx.lifecycle:lifecycle-viewmodel-ktx:$LIFECYCLE_VERSION'
like image 78
Sergey Avatar answered Jun 18 '26 03:06

Sergey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!