is it possible to filter and group Flow<List<Object A>>
by categories.
i found issue quite similar here , but no luck :(
here i'm sharing my approach which i tried,
code inside viewModel :
class HomeViewModel: ViewModel() {
data class Car(val id: Int, val name: String, val category: Int)
data class CarsByCategory(val categoryId:Int, val categoryName: String, val carList: List<Car>)
private val categoryList =
mapOf<Int, String>(1 to "Audi", 2 to "BMW", 3 to "Chevrolet", 4 to "Dodge", 5 to "Others")
private val mutableCarList: MutableList<CarsByCategory> = mutableListOf()
private val _mutableStateFlowCarList: MutableStateFlow<List<CarsByCategory>> = MutableStateFlow(emptyList())
val filteredCarList: StateFlow<List<CarsByCategory>> = _mutableStateFlowCarList
private fun getAllCarsAsFlow(): Flow<List<Car>> {
val cars = listOf(
Car(id = 1, name = "A1", category = 1),
Car(id = 1, name = "A2", category = 1),
Car(id = 1, name = "BMW X1", category = 2),
Car(id = 1, name = "BMW X7", category = 2),
Car(id = 1, name = "M Roadster", category = 2),
Car(id = 1, name = "Bolt EUV", category = 3),
Car(id = 1, name = "Blazer", category = 3),
Car(id = 1, name = "Challenger", category = 4),
Car(id = 1, name = "Neon", category = 4),
Car(id = 1, name = "Frontier", category = 5)
)
return flowOf(cars)
}
private fun filterCarByCategory(){
getAllCarsAsFlow().map { carList ->
for (key in categoryList.keys) {
val filteredList = carList.filter { car -> car.category == key }
mutableCarList.add(
CarsByCategory(
categoryId = key,
categoryName= categories.getValue(key),
carList = filteredList
)
)
}
_mutableStateFlowCarList.value = mutableCarList.toList()
}
}
init {
filterCarByCategory()
}
}
code in fragment:
....
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
lifecycleScope.launchWhenStarted {
homeViewModel.filteredCarList.collect {
Log.d(TAG, "onViewCreated: ${it.size}")
// here getting car list size is 0
}
}
}
...
i don't know is it right approach or not , please let me know how to solve this problem using flow
CodePudding user response:
A flow doesn't emit any value until it is collected. So you need to collect your flow:
private fun filterCarByCategory(){
viewModelScope.launch {
getAllCarsAsFlow().collect { carList ->
// Rest everything same
}
}
}
Edit: If the sole purpose of _mutableStateFlowCarList
is to provide data to UI, you need not use a StateFlow
here, just a normal Flow
would do the job.
val filteredCarList = getAllCarsAsFlow().map { carList ->
categoryList.map { (id, name) ->
CarsByCategory (
categoryId = id,
categoryName = name,
carList = carList.filter { car -> car.category == id }
)
}
}