androidandroid-jetpack-composeandroid-mvvmkotlin-stateflow

Flow data is not showing in jetpack compose


I'm trying to get data from server and cache into database and return new fetched list to user. I'm getting response form server and saving it to the local database but when im trying to observer it from composable function it showing list is empty.

When i try to debug and collect flow data in myViewModel class it showing but it not showing is composable function.

dao

@Dao
interface CategoryDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(categories: List<Category>)

    @Query("SELECT * FROM categories ORDER BY name")
    fun read(): Flow<List<Category>>

    @Query("DELETE FROM categories")
    suspend fun clearAll()
}

repository class:

    suspend fun getCategories(): Flow<List<Category>> {
        val categories = RetrofitModule.getCategories().categories
        dao.insert(categories)
        return dao.read()
    }

myViewModel

    fun categoriesList(): Flow<List<Category>> {
        var list: Flow<List<Category>> = MutableStateFlow(emptyList())
        viewModelScope.launch {
            list = repository.getCategories().flowOn(Dispatchers.IO)
        }
        return list
    }

Observing from:

@Composable
fun StoreScreen(navController: NavController, viewModel: CategoryViewModel) {
    val list = viewModel.categoriesList().collectAsState(emptyList())
    Log.d("appDebug", list.value.toString()) // Showing always emptyList []
}

current response :

2021-05-15 16:08:56.017 5125-5125/com.demo.app D/appDebug: []

Solution

  • You are never updating the value of MutableStateFlow which has been collected as state in the Composable function.

    Also you are assigning a Flow type object to a MutableStateFlow variable.

    We can just update the value of the collected flow in the compose using:-

    mutableFlow.value = newValue
    

    We need to change the type of list to MutableStateFlow<List<Category>> instead of Flow<List<Category>>

    Try this:-

     var list: MutableStateFlow<List<Category>> = MutableStateFlow(emptyList()) // changed the type of list to mutableStateFlow
     viewModelScope.launch {
        repository.getCategories().flowOn(Dispatchers.IO).collect { it ->
             list.value = it
        }
     }