Search code examples
androidkotlinandroid-roomkotlin-coroutineskotlin-flow

Fetch data from Room with Flow


Hi guys I cannot fetch data from my database:

I have in my DAO:

   @Transaction
    @Query("SELECT * FROM ClientEntity")
    fun getClients(): Flow<List<ClientEntity>>

RepoImpl:

 override suspend fun getClients(): Flow<List<ClientEntity>> {
        return clientDao.getClients()
    }

ViewModel:

fun getClients(): Flow<List<Client>> = flow {
        val clients = mutableListOf<Client>()
        clientsRepository.getClients().collect { clientEntities ->
            clients.addAll(clientEntities.map { it.toClient() })
        }
        emit(clients)
    }

Screen:

LaunchedEffect(key1 = myContext) {  
            viewModel.getClients().collect{
                val clients = viewModel.getClients()
                Log.d(TAG, "ClientsListScreen: da $clients")
            }
        
    }

Im using jetpack compose, with this code I dont see logd in my Screen. I know that are clients in my database since I inspected it.


Solution

  • First remove suspend keyword of getClients() from everywhere

    You can also improve your View Model code like this

    private val _clientResponse: MutableState<ClientState> = mutableStateOf(WeatherState())
        val clientResponse: State<ClientState> = _clientResponse
    
    
    viewModelScope.launch {
                    repository.getClients()
                        .onStart {
                             _clientResponse.value = ClientState(
                        isLoading =  true
                    )
                        }.catch {
                             _clientResponse.value = ClientState(
                        error = it.message ?: "Something went wrong"
                    )
                        }.collect{
                             _clientResponse.value = ClientState(
                        data = it
                    )
                        }
                }
    
    
    data class ClientState(
        val data: List< ClientEntity > = emptyList(),
        val error: String = "",
        val isLoading: Boolean = false
    )
    

    In Composable function

    val clientResponse = viewModel.clientResponse.value
    
    if (clientResponse.data.isNotEmpty())
     // do something
    
    if (clientResponse.error.isNotEmpty)
    // do something
    
    if(clientResponse.isLoading)
    // do something